Setting up Satchmo on a Debian Server

At the request of people on the satchmo-users mailing list, here’s my step-by-step guide to installing Satchmo on a Debian server. Debian is a wonderful base for Satchmo, much easier to set up and maintain than RedHat in my opinion. The magic is in the “apt” packaging system, it simply eliminates most of the ugly tracking-down of the right versions of software and their dependencies. This is a step-by-step, not a full discussion. To read more about “why”, please see the excellent article Creating my Dream Server for Django, which I heavily borrowed from.

Step by Step

Notes: If for this example, I am using the name “jschmoe” as the non-privileged user, and the fictional domain name “” as the domain. The “slug” will be “example” whenever I don’t need the full domain name. 1) Get root or sudo access to a server. If you need a Debian VPS, Rimuhosting is a solid choice. 2) If you have root, set up non-privileged user.

[root]$ useradd jschmoe
[root]$ passwd jschmoe

3) As root, give user sudo access

[root]$ visudo

Edit the file, adding yourself to the list.

jschmoe ALL=(ALL) ALL

confirm you have sudo access.

[jschmoe]$ sudo su

4) disable root login

[root]$ passwd -l root

5) Set up SSH key for password-less login. See these instructions (wherever it says [root] from now on, you can just use sudo or simply use “sudo su” to become root for the bulk of the install) 6) Install Aptitude

[root]$ apt-get install aptitude
[root]$ aptitude update

7) Turn off Apache using whatever tools came with your vps. I used Webmin -> System -> Bootup and shutdown -> apache2 -> “do not start at bootup” -> save If you don’t have a management console, go to the CLI and type

[root]$ update-rc.d apache2 remove

icon cool Setting up Satchmo on a Debian Server Stop Apache.

[root]$ /etc/init.d/apache2 stop

7) Install lighttpd

[root]$ aptitude install lighttpd

icon cool Setting up Satchmo on a Debian Server Test that lighty is installed

$ lynx localhost

(should see a server page) 9) Install python2.5 (why not?)

[root]$ aptitude install python2.5 python2.5-dev

Edit /usr/share/python/debian_defaults to this:

# the default python version
default-version = python2.5

# all supported python versions
supported-versions = python2.4, python2.5

# formerly supported python versions
old-versions = python2.3

# unsupported versions, including older versions
unsupported-versions = python2.3

Change the symlink /usr/bin/python to point to python2.5

[root]$ cd /usr/bin
[root]$ rm python
[root]$ ln -s python2.5 python
[root]$ pycentral updatedefault python2.4 python2.5

10) install easy_install

$ wget
[root]$ python ./

11) Install ipython (invaluable)

[root]$ easy_install ipython

12) Install PIL (didn’t work from easy_install for some reason)

[root]$ aptitude install atool
$ wget
$ aunpack Imaging-1.1.6.tar.gz
$ cd Imaging-1.1.6
[root]$ python install

13) (optional) Install memcached

[root]$ aptitude install memcached

Edit the /etc/memcached.conf file to your liking. I changed these:

#small VPS
-m 16
# default port
-p 11211
# run same as lighttpd user
-u www-data
# only listen locally

Restart memcached

[root]$ /etc/init.d/memcached restart

Install python memcached

$ wget
$ cd python-memcached-[tab]
[root]$ python install

14) Install subversion

[root]$ aptitude install subversion

15) Install PostgreSQL

$ aptitude install postgresql-8.1 postgresql-server-dev-8.1

Configure it. (From Make sure to use your own password instead of just ‘password’ in the code below.

[root]$ su postgres -c psql template1
ALTER USER postgres WITH PASSWORD 'password';

Edit /etc/postgresql/8.1/main/pg_hba.conf: Go to the end of the file and comment out all lines that start with host (unless you will be accessing your database remotely). Finally the local line should look like

local  all all password

Notice the last part, “password”. This is not the default for Debian, and it won’t work with Django unless you change this. Restart postgres:

[root]$ /etc/init.d/postgresql-8.2 restart

16) Install Psycopg2

$ wget
$ aunpack psycopg2-latest.tar.gz
[root]$ cd psycopg2-[tab]

17) Set up convenient permissions. For example:

[root]$ groupadd webdev
$ groups jschmoe
jschmoe : jschmoe

Add webdev to jschmoe, and set it primary

[root]$ usermod -G jschmoe,webdev jschmoe
[root]$ usermod -g webdev jschmoe
[root]$ groups jschmoe
jschmoe : jschmoe webdev

Now make webdev have access to your newly created files and dirs by default. This is appropriate and fine on a dedicated server like this, almost no where else. Edit your non-privileged user account ~/.bash_profile, adding or updating your umask like so:

umask 002

18) Decide where you are going to put framework code, webapps and media files. I like /opt. Set it up with the new group.

$ cd /opt
$ mkdir framework www webapps logs
$ chgrp framework webdev www webapps logs
$ chmod g+w framework www webapps logs

Log all the way out and log back in as your non-root user, try to make a new dir

$ cd /opt/framework
$ mkdir django
$ ls -l

You should see something like this:

total 4
drwxrwxr-x 2 jschmoe webdev 4096 2007-08-23 21:40 django

19) Push Django code. I recommend not just downloading from Djangoproject. Instead push from your dev box. I use and love the tool “unison” to push files and set up syncing. It is very smart, and conserves bandwidth, only pushing changes after the initial sync. Don’t worry, if you manually copy something, you won’t freak it out. It checks the hash of every file before syncing and asks you what to do if it is confused. Much like Rsync, but without the hateful, ugly syntax and danger of accidental file wipeout (hard won knowledge there).

[root] $ aptitude install unison

Now open a new terminal window, and push the code from your box to the server.

[you@your-dev-box] $ unison django ssh://

Follow the prompts, basically push everything to your new server. Example:

[bruce@invisible:/opt/webapps]$ unison /usr/local/pythonlibs/django/django ssh://
Contacting server...
Looking for changes
Warning: No archive files were found for these roots.  This can happen either
because this is the first time you have synchronized these roots,
or because you have upgraded Unison to a new version with a different
archive format.

Update detection may take a while on this run if the replicas are

Unison will assume that the 'last synchronized state' of both replicas
was completely empty.  This means that any files that are different
will be reported as conflicts, and any files that exist only on one
replica will be judged as new and propagated to the other replica.
If the two replicas are identical, then no changes will be reported.
Press return to continue.[<spc>]   bin/
  ( ... snip ... )
  Waiting for changes from server
  Reconciling changes

  file     ---->    [f]
  dir      ---->            bin  [f]
  dir      ---->            conf  [f]
  dir      ---->            contrib  [f]
  dir      ---->            core  [f]
  dir      ---->            db  [f]
  dir      ---->            dispatch  [f]
  dir      ---->            forms  [f]
  dir      ---->            http  [f]
  dir      ---->            middleware  [f]
  dir      ---->            newforms  [f]
  dir      ---->            oldforms  [f]
  dir      ---->            shortcuts  [f]
  dir      ---->            template  [f]
  dir      ---->            templatetags  [f]
  dir      ---->            test  [f]
  dir      ---->            utils  [f]
  dir      ---->            views  [f]

  Proceed with propagating updates? [] y
  Propagating updates

  ( ... snip ...)
  UNISON finished propagating changes at 14:56:36 on 23 Aug 2007

20) Push Satchmo to the server

[bruce@invisible:/opt/webapps]$ unison /usr/local/pythonlibs/satchmo/satchmo ssh://

21) Push your webapp and media files.

[bruce@invisible:/opt/webapps]$ unison /opt/webapp/example ssh://
[bruce@invisible:/opt/www]$ unison /opt/www/media.example ssh://

22) Install Satchmo and Django for Python. The easiest way is just to symlink them into the site-packages dir. While you are at it, link in your webapp.

[root]$ cd /usr/local/lib/python2.5/site-packages/
[root]$ ln -s /opt/framework/django .
[root]$ ln -s /opt/framework/satchmo .
[root]$ ln -s /opt/webapps/example .

23) Setup Satchmo’s remaining requirements Crypto module:

$ wget
$ cd pycrypto-2.0.1
[root]$ python install


$ wget
$ aunpack ReportLab_2_1.tgz
$ cd Reportlab_2_1/reportlab
[root]$ python install


$ wget
$ aunpack trml2pdf.tar.gz
[root]$ mv trml2pdf/trml2pdf /usr/local/lib/python2.5/site-packages/


[root]$ easy_install docutils


[root]$ easy_install PyYaml


[root]$ easy_install flup

24) Setup DB

[root]$ sudo su postgres
[root]$ createuser -P pg_yourusername
# should not be a superuser, do give it create database powers
[root]$ createdb --encoding=UNICODE db_yourtable -O pg_yourusername

25) configure Put in your db information and correct paths to your server paths. 26) run

$ ln -s /opt/framework/satchmo/tax .
$ python

27) Set up Lighttpd. Feel free to use these files as your base. I usually put the config files right in the webapp tree, so that when I push it, I have it conveniently there for copying into place. So for me, configuring is a matter of copying the files into place.

[root]$ cd /etc/lighttpd
[root]$ mv lighttpd.conf lighttpd.conf.bak
[root]$ cp /opt/webapps/example/etc/lighttpd/lighttpd.conf .
[root]$ /etc/init.d/lighttpd restart

Once it is restarted, you will want to test whether lighttpd is responding properly. You can do this even before we start the server by hitting the server at your static address. I usually just try to pull up the site CSS file. If your host isn’t resolving yet, you can just put an entry in your local /etc/hosts file for testing. Lighttpd will still see it in the header and respond correctly. 28) Start your server in test mode, from the webapps/example dir.

$ python ./ --verbosity=2 runfcgi host= port=11666 pidfile=~/ daemonize=false

Hit your server. It should work! Stop the server with ctrl-C. 29) Copy your init script into place, install it, and start the store

[root]$ cp etc/init.d/example_app /etc/init.d/
[root]$ mkdir /etc/sysconfig
[root]$ cp etc/sysconfig/example /etc/sysconfig/example
[root]$ update-rc.d example defaults
[root]$ /etc/init.d/example start

30) Hit the front page of your store. It should be working!

Coders Eye - Web Dev Tutorials and How-To Guides for Beginners
Enable registration in settings - general