Installing Pootle on Debian Etch, The Easiest Way

Pootle is a user-friendly web application for online translation of contents. It’s used by organizations like Creative Commons, and GNU/Linux Matters.

I’m going to show you how to install it the easiest way, from my experience with the GLM Translation Service under Debian 4.0 (this guide might also work under Ubuntu, though). I’ll use the sudo utility, so I assume that you’ve already installed and configured sudo accordingly for your user.

Installing dependencies

Some of the Pootle’s dependencies are available in Debian repositories, so we may install them by running:
sudo aptitude install python-dev python-pysqlite2 python-celementtree subversion bzip2 g++ curl

We’re now going to install the other software packages required by Pootle. First, select the directory where you want to download and compile your software, for example:
cd /usr/src

To get the source code of the packages and extract them, run the following commands:
curl | tar xzv
curl | tar xjv
curl | tar xjv
curl | tar xzv

Installing the applications:
sudo python translate-toolkit-1.1.1/ install
sudo python kid-0.9.6/ install
sudo Pootle-1.1.0/ install
sudo jToolkit-0.7.8/ install

Do not install PyLucene

Pootle is supposed to work better with PyLucene, but if you (like me) hate headaches, you won’t install PyLucene on Debian Etch. If you try to install it, you’d get this error:
install: cannot stat `/usr/lib/security/': No such file or directory
make: *** [install] Error 1

There’s nothing you could install that would create that file; don’t you even try to create it as an empty file: You’d be able to install PyLucene, but Pootle won’t work and you’d get this error when you’ll try to run it:
GC Warning: Repeated allocation of very large block (appr. size 65536):
May lead to memory leak and poor performance.

If it’s too late, and you’ve already installed PyLucene with as an empty file (as suggested in some mailing-lists), you may fix it by running the following commands:
sudo mv /usr/lib/python2.4/site-packages/ /usr/lib/python2.4/site-packages/
sudo mv /usr/lib/python2.4/site-packages/ /usr/lib/python2.4/site-packages/
sudo mv /usr/lib/python2.4/site-packages/PyLucene.pyc /usr/lib/python2.4/site-packages/PyLucene.pyc.old

Don’t you have a mail server?

If your mail server is not in the same host as Pootle, you’ll need to install one. Just run the command below to install Postfix and then select “Internet website” when asked about what you’ll use postfix for:
sudo apt-get install postfix

Configuring Pootle

To make it easy for you to configure and play with Pootle, I suggest you create softlinks to Pootle’s configuration files in a folder like /etc/pootle:
sudo mkdir /etc/pootle
sudo ln /usr/lib/python2.4/site-packages/Pootle/pootle.prefs -s /etc/pootle/pootle.conf
sudo ln /usr/lib/python2.4/site-packages/Pootle/users.prefs -s /etc/pootle/users.conf
sudo ln /usr/lib/python2.4/site-packages/Pootle/html -s /etc/pootle/html
sudo ln /usr/lib/python2.4/site-packages/Pootle/templates -s /etc/pootle/templates

This way, any file you might ever need to edit will be in /etc/pootle.

Now let’s edit the main configuration file in Pootle: sudo nano /etc/pootle/pootle.conf

It’s well-documented, so I won’t talk a lot about it. I just suggest you only set the following parameters accordingly:

  • description: Describe your website powered by Pootle, with a text aimed at (potential) translators.
  • fromaddress.
  • supportaddress: The email address for translators to make questions. This might be a mailing list.
  • defaultrights: I suggest you set it to defaultrights = "view, suggest, archive, pocompile, translate, commit"
  • podirectory: It’s the path to your translation files. For this HOWTO I’ll use /var/translations.

Your pootle user

I suggest you create a user for running pootle:
sudo adduser --disabled-password --disabled-login pootle

Setting up service scripts for Pootle

Create the file /etc/init.d/pootle as root with the following contents:
# /etc/init.d/pootle: start and stop the Pootle Server
# Pootle runs as user -pootle- via sudo
# This script is based on the one published here
test -x /usr/bin/PootleServer || exit 0
. /lib/lsb/init-functions
case "$1" in
log_begin_msg "Starting Pootle Server..."
/usr/bin/sudo -u pootle $PREFIX/start_pootle &
log_end_msg 0
log_begin_msg "Stopping Pootle Server..."
$PREFIX/stop_pootle >/dev/null 2>&1
log_end_msg 0
log_begin_msg "Stopping Pootle Server..."
$PREFIX/stop_pootle >/dev/null 2>&1
log_end_msg 0
log_begin_msg "Starting Pootle Server..."
sudo -u pootle $PREFIX/start_pootle &
log_end_msg 0
log_success_msg "Usage: /etc/init.d/pootle {start|stop|restart|status}"
exit 1
exit 0

Now let’s create, as root, the auxiliary scripts required by the script above:


# $PREFIX/start_pootle
# Start script in port 8080, separates errors from normal logs
# based on a script published here:
export HOME="/home/pootle"
/usr/bin/PootleServer -p 8080 $@ >> /var/log/pootle/`date "+%F"` 2>> /var/log/pootle/`date "+%F"`.err


# Stop script $PREFIX/stop_pootle
# based on a script published here:
echo "Killing Pootle"
pidpootle=`ps -ef |grep PootleServer |grep python | awk '{print $2}'`
pidpootle2=`ps -ef |grep start_pootle |grep bin | awk '{print $2}'`
kill $pidpootle2 >/dev/null 2>&1
kill $pidpootle >/dev/null 2>&1


# Pootle Status $PREFIX/status_pootle
# based on a script published here:
pidpootle=`ps -ef |grep PootleServer |grep python | awk '{print $2}'`
if [ "$pidpootle" != "" ]
echo "Pootle Server running in pid ($pidpootle)"
echo "Pootle Server is not running"

Make them work!

Now we have to make these scripts useful:
sudo chmod +x /etc/init.d/pootle
sudo chmod +x /usr/local/pootle/s*
sudo update-rc.d pootle

Configuring Pootle to use your repository

Pootle supports several VCSs, but I’ll only teach you how to setup a Subversion working copy that Pootle may update and commit. If you don’t use a version control system, I recommend you do so. If you’re sure you don’t need it, you may skip this section. If you’re using another VCS, you’ll need to go to the Pootle’s website to learn how to configure it with Pootle.

Setup your working copy

Let’s create the working copy at, say, /var/translations. To do that in GNU/Linux Matters, we would run:
sudo svn co /var/translations
You should replace the URL by yours.
And don’t forget to set the pootle user as the owner:
sudo chown pootle -R /var/translations

Create basic cronjobs

We should run from time to time two scripts:

  • One to commit the changes made by translators; ideally, these changes would be committed by translators themselves, but from my experience you should not count on that (most of them forget about it or just don’t know they can do that).
  • Another to update your PO templates from the repository.

So we’re going to ask our pootle user to do this by creating cronjobs. First, become pootle:
sudo su - pootle
Then run crontab -e and add the following two lines:
*/15 * * * * /usr/bin/svn update /var/translations >> /dev/null 2>> /home/pootle/update.err
0 0,8,16 * * * /usr/bin/svn commit -m "Uncommitted translations in the last 8 hours" /var/translations >> /dev/null 2>> /home/pootle/commit.err

Pootle is running on port 8080

For security reasons, if you followed this HOWTO you’ll be running as the pootle user, not as root. And due to a UNIX misfeature, only root may open ports below 1024. So, unless you love appending the port number to your URLs, and if port 80 is available on your system, you’d proxy Pootle through a webserver.

The proxy trick is recommended, but if you cannot do that or just don’t want, you can use iptables to redirect traffic from port 8080 to 80. My suggestion would be to use the next iptables ruleset:
# Generated by iptables-save v1.3.6 on Thu Jan 24 16:40:59 2008
-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
# Completed on Thu Jan 24 16:40:59 2008
# Generated by iptables-save v1.3.6 on Thu Jan 24 16:40:59 2008
:OUTPUT ACCEPT [495:60715]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state INVALID -j DROP
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A FORWARD -j REJECT --reject-with icmp-port-unreachable
# Completed on Thu Jan 24 16:40:59 2008

For more information about this basic iptables-based firewall, you may read my Setting up your first server HOWTO.

Criticism? Suggestions? Complaints?

Leave a comment!