Tag Archives: centos

Installing Django on CentOS

These are notes for what I did to get Django working on CentOS.

Activate EPEL.

Use the appropriate version, of course. I used:

[bash light=”true”]
$ sudo rpm -Uhv http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

Install Prerequisites

  1. Install Apache.
    1. Ensure it’s working, including ensuring the firewall lets traffic through.
  2. Install MySQL
  3. Install revision control or however you pull software, e.g. git.
    1. Create a non-priviledged user, if that’s you install your software.
    2. Ensure Apache can access the software directory.

Install Django

[bash light=”true”]
$ sudo yum install python Django mod_python MySQL-python

Test Django

[python light=”true”]
$ python
Python 2.6.6 (r266:84292, Feb 22 2013, 00:00:18)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> print django.get_version()

Install and Test the Software

I create a separate user for managing the code via git.
Put the code somewhere appropriate, e.g. /opt.

  1. The address tells Django to accept external connections.
  2. Ensure the test port is open on the firewall.

[bash light=”true”]
$ cd /opt/foo
$ python manage.py runserver

Attempt to connect to your application. Ensure, for example, that the settings allow database access.

Running Django from Apache WSGI

Create an Apache WSGI file.

[bash light=”true”]
$ cd /opt/foo
$ mkdir apache
$ vim apache/django.wsgi

and fill the file with something like:

import os
import sys


os.environ[‘DJANGO_SETTINGS_MODULE’] = ‘foo.settings’

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()


Inside of the Apache virtual host:

<VirtualHost *:80>
ServerName foo.bar.com

WSGIScriptAlias / /opt/foo/apache/django.wsgi

# Alias /robots.txt /opt/foo/static/robots.txt
# Alias /favicon.ico /opt/foo/static/favicon.ico
Alias /static/admin/ /usr/lib/python2.6/site-packages/django/contrib/admin/media/
Alias /static/ /opt/foo/static/

<Directory /opt/foo>
Order allow,deny
Allow from all

<Directory /opt/food/static>
Order deny,allow
Allow from all

Restart the Apache server.

Test to ensure that you can connect.


A big shout out to ITek Blog’s article Installing Python / Django on Centos 6.3 is Easy!.

Installing Django on CentOS 6

Django is available as an EPEL package.

First, activate EPEL via

[code lang=”bash”]
$ sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

or for 32-bin CentOS,

[code lang=”bash”]
$ sudo rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

NOTE: That exact URL will change with time. I took it from the EPEL FAQ.

Next, install the Django package.

[code lang=”bash”]
$ sudo rpm install Django

Ensure that Django is working.

[code lang=”python”]
$ python
Python 2.6.6. (r266:84292, Feb 22 2013, 00:00:18)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or license" for more informaiton.
>>> import django
>>> print django.get_version()
>>> _

Automatic OS Updates in CentOS

The yum dæmon is capable of controlling updates to fit a variety of scenarios.

The configuration file can be edited with

$ sudo vim /etc/yum/yum-updatesd.conf

Edit the file thus:

  • Change “emit_via = dbus” to “emit_via = email”. This tells the yum dæmon to use e-mail to send an alert.
  • Add “email_to = youremail@domain.com
  • Add “email_from = root@mail.domain.com
  • Change do_download to yes if you want the yum dæmon to automatically download the updates.
  • Change do_download_deps to yes if you changed do_download to yes.

It should look similar to:

  # how often to check for new updates (in seconds)
  run_interval = 3600
  # how often to allow checking on request (in seconds)
  updaterefresh = 600

  # how to send notifications (valid: dbus, email, syslog)
  emit_via = email
  email_to = sysadmin@domain.com
  email_from = root@mail.domain.com
  # should we listen via dbus to give out update information/check for
  # new updates
  dbus_listener = yes

  # automatically install updates
  do_update = no
  # automatically download updates
  do_download = yes
  # automatically download deps of updates
  do_download_deps = yes

Installing Zimbra 7 on CentOS

These are personal notes for installing Zimbra 7 on Centos 5, including split DNS for servers behind firewalls.



  • This is for a small installation, where a single server can handle everything.
  • Zimbra is not officially supported on CentOS, even though it comes directly from RHEL’s sources. If you need support from the company, don’t use it.


  • Zimbra 7 is 64-bits. Don’t use the 32-bit versions since they are officially deprecated and are slated to be dropped.
  • If you are installing directly onto bare metal, there should be no problem.
  • If you are installing in a virtual machine, then ensure that the processor has the physical hardware support for 64-bit virtualization, i.e. Intel VT or AMD-V. (None of the older machines that I have support).
  • At least 1.5 GB RAM as an absolute minimum, but Zimbra may be slow at times. The Quick Start guide recommends 4GB.
  • Zimbra will run on a single processor; two are better.
  • I can’t recommend starting with less than 20-40GB HD space. I anticipate adding disks and expanding the file system as needed.

Virtual Machine

  • I like to name the (virtual) physical disks pv00, pv01, pv02, etc. (pv=physical volume) so they’re easy to track.
  • The NIC must be bridged. Save yourself the pain.
  • I remove the floppy disk, sound, card, and printer.

Installing CentOS

Disk Layout

  • I generally create two partitions: /boot and the rest a LVM partition
  • Inside I create a volume group with the name vg00, and create inside of it:
    • lvRoot mounted on /
    • lvTmp mounted on /tmp
    • lvVar mounted on /var
    • lvOpt mounted on /opt
    • lvSwap
    • Unallocated space for expansion of any non-lvOpt partition that threatens to get full. I treat lvOpt differently because it’s the mail storage partition, and if it fills up I want to at least double the amount of space available. If /opt starts to get full, I will:
      • add a whole new disk,
      • add it as a physical volume,
      • expand the volume group with the physical volume,
      • expand lvOpt, and
      • expand the /opt filesystem.

Package Selection

Note that this is not fine tuned, and more akin to a shotgun approach. Even though RHEL is an officially-supported OS, there does not appear to be any recommendations from Zimbra on which package groups to install. This section will be updated if I can find more information.

  • For package selection, deselect Desktop – Gnome.
  • Select Customize now
  • Click Next
  • Ensure that only the following categories are selected for install. Note: This is for simplicity. It does not attempt to strip the system down to its bare nubs.
    • Applications
      • Editors
    • Development
      • Development Libraries
      • Development Tools
      • Legacy Software Development
    • Base System
      • Administration Tools
      • Base
      • Legacy Software Support

First-Time Setup


I noticed that ntpd was not being started. Ensure that it’s checked in the services list or run

chkconfig ntpd on

Firewall Configuration

  • SELinux: Disabled
  • Customize open ports:
    • SSH
    • WWW (HTTP)
    • Secure WWW (HTTPS)
    • Mail (SMTP)
    • Other ports: 143, 993, 110, 995, 7071

Zimbra will not function correctly with SELinux enabled. A reboot is required.

Operating System Finalization

Apply Operating System Updates

Log in as root.

Use yum to update the server.

yum update -y

Package Preparation

Remove sendmail.

yum erase sendmail

Interestingly, this also removes redhat-lsb and mdadm. I’m installing this on a virtual machine that resides on a disk that is already mirrored, so I don’t use any soft RAID.

Ensure dependencies are installed.

yum install gmp compat-libstdc++-33 sysstat sudo libidn wget libtool-ltdl

With the current version of CentOS (5.5), this only installs sysstat and libtool-ltdl.

Visually Verify the /etc/hosts File

The /etc/hosts file should look something like:

# Do not remove the following line, or various programs
# that require network functionality will fail.		localhost.localdomain localhost
::1			localhost6.localdomain6 localhost6
aaa.bbb.ccc.ddd		yourhostname.yourdomain.com yourhostname

Where aaa.bbb.ccc.ddd is the local behind-the-firewall IP address for the server. Note: This was set to the external IP address for some reason.

If the server resides behind a firewall, the IP address is the local address behind the firewall, which may not match what DNS returns. (The discrepancy will be taken care of below.)

If Behind a Firewall (Set Up Split DNS)

If the server is behind a firewall, split DNS needs to be set up so that when Zimbra tries to perform a lookup for the server, the normal DNS lookup is short-circuited, and the behind-the-firewall IP address comes back to Zimbra.

Install Bind

yum install bind bind-chroot bind-libs bind-utils

Ensure bind starts automatically.

 chkconfig named on

Create the named Configuration File

vim /var/named/chroot/etc/named.conf
chmod 644 /var/named/chroot/etc/named.conf

Insert the following. Be sure to change the forwarders IP address (eee.fff.ggg.hhh, iii.jjj.kkk.lll) to the IP addresses of the old DNS server. Be sure to replace domain.com with your own domain.

options {
    directory "/var/named";
    dump-file "/var/named/data/cache_dump.db";
    statistics-file "/var/named/data/named_stats.txt";
    forwarders {
        eee.fff.ggg.hhh ;
        iii.jjj.kkk.lll ;
include "/etc/rndc.key";
// Specify that this server is the master for mail.domain.com
zone "mail.domain.com" {
    type master;
    file "db.mail.domain.com";

Create the file described in the file line. Be sure to change domain.com to the domain of your server.

vim /var/named/chroot/var/named/db.mail.domain.com
chmod 644 /var/named/chroot/var/named/db.mail.domain.com

Insert the following. Also pay attention the fact that adminaccount.domain.com is the system administrator’s e-mail address adminaccount@domain.com. DNS turns the first period into the @ sign.

@       IN      SOA     mail.domain.com. adminaccount.domain.com. (
                               10118      ; Serial
                               43200      ; Refresh
                               3600       ; Retry
                               3600000    ; Expire
                               2592000 )  ; Minimum

               IN      NS      aaa.bbb.ccc.ddd
               IN      A       aaa.bbb.ccc.ddd
               IN      MX      10 mail.domain.com.

Adjust resolv.conf

Adjust the resolv.conf file to search the local server for primary DNS

vim /etc/resolv.conf

Change it to look like:

search domain.com
nameserver aaa.bbb.ccc.ddd

Start the named Dæmon

chkconfig named on
service named start

Check its operation with:

dig mail.domain.com mx

It should return something similar to:

; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5_5.3 <<>> mail.domain.com mx
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40071
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;mail.domain.com.		IN	MX

mail.domain.com.	2592000	IN	MX	10 mail.domain.com.

mail.domain.com.	2592000	IN	NS	aaa.bbb.ccc.ddd.mail.domain.com.

mail.domain.com.	2592000	IN	A	aaa.bbb.ccc.ddd

;; Query time: 1 msec
;; SERVER: aaa.bbb.ccc.ddd#53(aaa.bbb.ccc.ddd)
;; WHEN: Sat Mar 12 17:42:25 2011
;; MSG SIZE  rcvd: 93


dig mail.domain.com any

should return something like:

; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5_5.3 <<>> mail.domain.com any
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1326
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0

;mail.domain.com.		IN	ANY

mail.domain.com.	2592000	IN	SOA	mail.domain.com. sysadmin.domain.com. 10118 43200 3600 3600000 2592000
mail.domain.com.	2592000	IN	NS	aaa.bbb.ccc.ddd.mail.domain.com.
mail.domain.com.	2592000	IN	A	aaa.bbb.ccc.ddd
mail.domain.com.	2592000	IN	MX	10 mail.domain.com.

;; Query time: 1 msec
;; SERVER: aaa.bbb.ccc.ddd#53(aaa.bbb.ccc.ddd)
;; WHEN: Sat Mar 12 17:43:23 2011
;; MSG SIZE  rcvd: 138

The final check is the following. Note! This must be typed verbatim!

host $(hostname)

Should return something like:

mail.domain.com has address aaa.bbb.ccc.ddd
mail.domain.com mail is handled by 10 mail.domain.com.

Adjust the Yum Update Dæmon

It may be advisable to tweak the yum dæmon so that it automatically downloads updates and sends an e-mail to notify you that the machine can be updated. Details on how to do that may be found here.

Install Zimbra

Download Zimbra

Download the 64-bit version of Zimbra for Red Hat Enterprise Linux 5 here. I just right click on the link and paste it onto the command line, and make liberal use of tab completion in bash. For example:

cd /tmp
wget wget http://files2.zimbra.com/downloads/7.0.1_GA/zcs-7.0.1_GA_3105.RHEL5_64.20110304210645.tgz
tar xvzf zcs-7.0.1_GA_3105.RHEL5_64.20110304210645.tgz
cd zcs-7.0.1_GA_3105.RHEL5_64.20110304210645

Run the Installer

Run the install script.

./install.sh --platform-override

You must include the platform override option, else the installer will abort with the following error:

You appear to be installing packages on a platform different
than the platform for which they were built.

This platform is CentOS5_64
Packages found: RHEL5_64
This may or may not work.

Installation can not continue without manual override.
You can override this safety check with ./install.sh --platform-override

WARNING: Bypassing this check may result in an install or
upgrade that is NOT usable.

You will go through the following steps.

  • License agreement. Type answer with “Y”.
  • Prerequisite check. This should pass cleanly.
  • Package self-test.
  • Select the packages to install. Accept the defaults.
    • zimbra-ldap
    • zimbra-logger
    • zimbra-mta
    • zimbra-snmp
    • zimbra-store
    • zimbra-apache
    • zimbra-spell
    • zimbra-memcached
    • zimbra-proxy
  • A warning that you are not running on Red Hat, with the question, “Install anyway?”. Answer with “Y”.
  • A warning that the system will be modified. Answer with “Y”.
  • Installing packages.
  • Administrative install menu.

On the administrative menu, the important item to do is to set the admin password.

When complete, use “a” to apply the changes, and confirm with “Yes”.

  • When complete, use “a” to apply the changes.
  • Confirm with “Yes”.
  • Accept the default configuration file name.
  • It will warn, “The system will be modified – continue?”. Answer with “Yes”.
  • The installer will set up a few more items, including creating a self-signed SSL certificate.
  • The installer will ask if you want to notify Zimbra of your installation. Your choice.
  • The installer will start the servers.
  • The installer will install zimlets &c.

At last you will see:

Configuration complete - press return to exit

At this point you can point the web browser to port 7071 of the server and log in as the administrator. The install is complete.


  • Zimbra documentation
  • An out-of-date but useful guide is on the Zimbra forums here.
  • Setting up split DNS can be found on the Zimbra wiki here.


Setting Up a Subversion Server

The last time I set up a Subversion server was 2005. Here are notes I jotted down while installing a new server. There are a few gotchas along the way. Hopefully these notes catch all of them.


The goal is to set up a dedicated virtual machine to act as a Subversion repository. It resides in-house, off of the Internet.


Subversion can be run in several different ways. Some of those ways create the potential for file ownership to become a problem, causing subversion to fail in various inconvenient manifestations. The method I chose is to use xinetd to launch the Subversion dæmon running as a user dedicated for this purpose.

Where to store the Subversion repository is a matter of personal philosophy. Here I’ll put it in /opt/subversion.

This opens up the Subversion server port 3690. If you’re running on a machine directly connected to the Internet, you can consider not opening up that port to the world, and securely tunneling port 3690 using ssh.


  • Set up the server as you wish. I used CentOS 5.
  • Create a user for Subversion. Note that RedHat (and thus CentOS) creates a corresponding group by default.
$ sudo /usr/sbin/useradd -c "Subversion" svn
  • Install Subversion, and xinetd if not installed. Open up port 3690 in the firewall.
$ sudo yum install subversion xinetd
$ sudo /sbin/chkconfig --level 35 xinetd on
$ sudo /sbin/iptables -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3690 -j ACCEPT
  • Create a Subversion configuration file for xinetd. Restart xinetd.
$ sudo vim /etc/xinetd.d/svn
$ sudo /etc/init.d/xinetd restart

The contents of the configuration file are along these lines:

service svn
    disable         = no
    socket_type     = stream
    wait            = no
    user            = svn
    server          = /usr/bin/svnserve
    server_args     = --inetd
    log_on_failure  += USERID
  • Prepare the directory for the subversion server.
$ sudo mkdir /opt/subversion
$ sudo chown svn.svn /opt/subversion
$ su svn -
$ svnadmin create --fs-type fsfs /opt/subversion/repository_name

Note that I’m not sure whether fsfs is default type for svnadmin nowadays, so I specified it explicitly. I don’t really see any reason to use Berkley DB and its associated risks for database corruption (a “wedged” database).

  • Edit the configuration files for your repository.
$ vim /opt/subversion/repository_name/conf/svnserve.conf
$ vim /opt/subversion/repository_name/conf/passwd

The passwd file is a plain text file with user names and passwords. The format should be obvious when you see the samples in the file. Note the security caveat here. This isn’t.

The server configuration file (svnserve.conf) values can be tailored to suit your needs. See the “Red Bean book” official documentation for details. (If you wish to support the project, you may consider buying the dead tree version from O’Reilley.) To allow only users with a password access to the repository, I used:

anon-access = none
auth-access = write
password-db = passwd
  • Test out the setup
$ su - fred
$ svn co svn://localhost/opt/subversion/repository_name

This should create a directory called repository_name. There should be nothing in it (except for the hidden .svn file).

  • It is common practice to create three subdirectories in a repository: branches, tags, and trunk.
$ cd repository_name
$ mkdir branches tags trunk
$ svn add branches tags trunk
$ svn commit -m "Create core directories for the repository"
  • If things have worked to this point, you should be able to use the repository from another computer using the URL svn://machine_name/opt/subversion/repository_name/trunk as you would normally.

WTF Nagios Installed?

Nagios is one of those Open Source projects that I’ve had a love-hate relationship with over the years. On one hand, it’s a powerful, popular tool. On the other it’s one where you are supposed to “just” grab the source, compile it, and install.

The the complication is the quotation marks around the word “just”. Despite the fact that I’m a reasonably accomplished software engineer, my experience over the years with “just” doing that has been less than stellar… to the point where unless it’s for hobby purposes, I tend to avoid those projects. They bring to mind the Shrek line “The Princess will be up the stairs in the highest room in the tallest tower.” At those points in time, I’m usually not in a position to slay the dragon and climb those stairs by troubleshooting other people’s code.

I ran into a situation where Nagios really would be very beneficial, so I decided to give it another chance. It is a popular active project and as such, is always improving. After perusing the web sites, reading the requirements, and finding a Fedora Quickstart page, I reached for my default tool of CentOS inside a virtual machine.

Quite frankly I was pleasantly surprised that there were zero problems following the instructions. Everything compiled, installed, and ran without complaint save one minor point. I say to the Nagios team, “Thank you.”

The minor point was SELinux. The instructions say to disable it, but give a couple of commands if you wish to keep it active. Those commands didn’t work as-is so I just disabled it for the time being. (Yes, yes, I know, I know… but that’s a discussion for another time.)