August 26, 2013

Installing Weblate from sources on Ubuntu 13.04 raring

Weblate is a web-based collaborative translation tool developed by Michal Čihař. Among its features includes full integration with the Git distributed version control system.

Following are the instructions to install Weblate from sources on Ubuntu 13.04 raring.

You will see highlighted the configuration settings that you should provide according to your system.

Initial server setup

We start with an empty machine with Ubuntu 13.04 installed. The first step is to update the system.

Assuming that you have a machine SSH key, open a terminal on the remote machine:

ssh -i your-machine-key-file.pem ubuntu@your-machine-public-dns

Update the package lists from the repositories and install the newest versions of the packages currently installed on the system:

sudo apt-get update
sudo apt-get upgrade

Close the remote terminal:

logout

Reboot the machine and, once the machine has restarted, open a new terminal on the remote machine:

ssh -i your-machine-key-file.pem ubuntu@your-machine-public-dns

Install the Network Time Protocol daemon to keep the machine clock synchronized:

sudo apt-get install ntp

Install Git

Git is a distributed version control system. Weblate uses Git to manage the translation versions.

Install the Git distributed version control system:

sudo apt-get install git

Install MySQL

Weblate can operate with various database backends, we have chosen MySQL for this installation. We will install a local MySQL instance (you can also use a remote server):

sudo apt-get install mysql-server

You will be prompted for the root user password, provide one and take note:

New password for the MySQL "root" user:
YOUR_MYSQL_ROOT_PASSWORD

Create the Weblate database and user

We will create a MySQL database and a user for Weblate, for this purpose open a MySQL shell:

mysql --user=root --password=YOUR_MYSQL_ROOT_PASSWORD

You will need to provide a password for the Weblate database user, provide one and take note. Paste the following to create the Weblate database:

USE mysql;
CREATE DATABASE weblate DEFAULT CHARACTER SET utf8;
GRANT ALL ON weblate.* TO 'weblate'@'localhost'
  IDENTIFIED BY 'YOUR_MYSQL_DB_PASSWORD';
exit;

Install Memcached

Memcached is a distributed memory object caching system, intended for speeding up dynamic web applications. We will install a local instance of memcached, as recommended.

sudo apt-get install memcached

Install the Apache HTTP server

Weblate is a Django web application. A Django web application normally runs behind a web server, and for this installation we have chosen the Apache HTTP server.

WSGI is a specification for web servers to communicate with Python web applications, we also install the WSGI adapter module for Apache.

sudo apt-get install apache2 libapache2-mod-wsgi

Create the Weblate system user

Create a new system user to run the Weblate application:

sudo adduser --system --group --home /var/opt/weblate \
  --gecos Weblate --shell /bin/sh weblate

Set the ownership of the weblate user home directory:

sudo chown -R weblate:weblate /var/opt/weblate

Create the directory to store the Git repositories:

sudo -u weblate mkdir /var/opt/weblate/repos

Create the directory to store the full-text indexes:

sudo -u weblate mkdir /var/opt/weblate/whoosh-index

Create a directory to store the SSH configuration and keys:

sudo -u weblate mkdir /var/opt/weblate/.ssh

Create the directory to store the log files:

sudo install --owner weblate --group weblate \
  --directory /var/log/weblate

Install the Weblate requirements

Install additional build dependencies:

sudo apt-get install python-dev gettext \
  libjpeg-dev libpng-dev \
  libxml2-dev libxslt-dev

Install the Weblate application dependencies:

sudo apt-get install python-django \
  python-django-registration python-django-south \
  python-social-auth python-imaging \
  python-pyicu python-git python-lxml \
  python-cairo python-gtk2 python-libravatar

A couple of Weblate dependencies are outdated in the Ubuntu repositories, so we will install these dependencies from the Python Package Index:

sudo apt-get install python-pip
sudo pip install --upgrade pillow
sudo pip install --upgrade whoosh
sudo pip install --upgrade translate-toolkit

Finally, as we opted for MySQL and Memcached, install the corresponding Python bindings:

sudo apt-get install python-mysqldb python-memcache

Download the Weblate source code

The Weblate source code is located in a public Github repository, clone the Git repository into the /opt/weblate directory.

sudo git clone https://github.com/nijel/weblate.git \
  /opt/weblate

Weblate configuration

The Weblate configuration is kept in a Django settings file, see Production setup in the Weblate documentation and Available settings in the Django documentation.

Copy the file weblate/settings_example.py to weblate/settings.py:

sudo cp /opt/weblate/weblate/settings_example.py \
  /opt/weblate/weblate/settings.py

Edit the Weblate settings file:

sudo nano /opt/weblate/weblate/settings.py

Disable Django’s debug mode:

DEBUG = False

Configure the mail smtp server settings, see EMAIL_BACKEND:

EMAIL_HOST = 'your-smtp-host'
EMAIL_PORT = 'your-smtp-port'
EMAIL_HOST_USER = 'your-smtp-user'
EMAIL_HOST_PASSWORD = 'your-smtp-password'
EMAIL_USE_TLS = True or False

Complete the list of people who get code error notifications, when a view raises an exception, Django will email these people with the full exception information, see ADMINS:

ADMINS = (
  ('Your Admin Name', 'your-admin-email@your-domain')
)

Configure the MySQL database settings, see DATABASES:

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'weblate',
    'USER': 'weblate',
    'PASSWORD': 'YOUR_MYSQL_DB_PASSWORD',
    'HOST': '127.0.0.1',
    'PORT': '3306',
  }
}

Set the time zone for this installation, see TIMEZONE:

TIME_ZONE = 'UTC'

By default, Weblate is configured to send the log information to syslog, you might want to store the log information into a separate log file, if if this is the case you can add a log file handler, see logging.handlers:

if DEBUG or not os.path.exists('/dev/log'):
    DEFAULT_LOG = 'console'
else:
    DEFAULT_LOG = 'logfile'
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'formatters': {
        'syslog': {
            'format': 'weblate[%(process)d]: %(levelname)s %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
        'logfile': {
            'format': '%(asctime)s %(levelname)s %(message)s'
        },
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'syslog': {
            'level': 'DEBUG',
            'class': 'logging.handlers.SysLogHandler',
            'formatter': 'syslog',
            'address': '/dev/log',
            'facility': SysLogHandler.LOG_LOCAL2,
        },
        'logfile': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': "/var/log/weblate/weblate.log",
            'maxBytes': 100000,
            'backupCount': 3,
            'formatter': 'logfile',
        },
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins', 'logfile'],
            'level': 'ERROR',
            'propagate': True,
        },
        'weblate': {
            'handlers': [DEFAULT_LOG],
            'level': 'DEBUG',
        }
    }
}

You need to provide a secret key for this particular Django installation, it is used to provide a seed in secret-key hashing algorithms, see SECRET_KEY:

SECRET_KEY = 'YOUR_SECRET_KEY'

You can generate a random key with the following command:

openssl rand -base64 36

Edit the full path of the directory where the Git repositories are stored, this directory needs to be writable, see GIT_ROOT:

GIT_ROOT = '/var/opt/weblate/repos/'

Offload the updating of the full-text index to a separate process. Later we will configure a CRON job to update the index, see OFFLOAD_INDEXING:

OFFLOAD_INDEXING = True

Provide the full path of the directory where to put the full-text indexes, this directory needs to be writable, see WHOOSH_INDEX:

WHOOSH_INDEX = '/var/opt/weblate/whoosh-index'

Edit the list of domain names that this Django site can serve, see ALLOWED_HOSTS:

ALLOWED_HOSTS = ['.your-domain']

As we installed Memcached configure the default cache backend, see CACHES.

CACHES = {
  'default': {
    'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
    'LOCATION': '127.0.0.1:11211',
  }
}

You can enable one or more Machine Translation services by providing the appropriate API keys.

If you want to use the Microsoft Translator service, register at Microsoft Translator, and configure your ID and secret:

MT_MICROSOFT_ID = 'YOUR_MICROSOFT_ID'
MT_MICROSOFT_SECRET = 'YOUR_MICROSOFT_SECRET'

If you want to use the Google Translate API you will need a Google API key, see Translate API Getting Started:

MT_GOOGLE_KEY = 'YOUR_GOOGLE_KEY'

You must enable the machine translation services that you have configured:

MACHINE_TRANSLATION_SERVICES = (
#    'trans.machine.apertium.ApertiumTranslation',
#    'trans.machine.glosbe.GlosbeTranslation',
     'trans.machine.google.GoogleTranslation',
#    'trans.machine.google.GoogleWebTranslation',
     'trans.machine.microsoft.MicrosoftTranslation',
#    'trans.machine.mymemory.MyMemoryTranslation',
#    'trans.machine.opentran.OpenTranTranslation',
#    'trans.machine.tmserver.AmagamaTranslation',
#    'trans.machine.tmserver.TMServerTranslation',
#    'trans.machine.weblatetm.WeblateSimilarTranslation',
#    'trans.machine.weblatetm.WeblateTranslation',
)

Configure the email address that error messages come from:

SERVER_EMAIL = 'your-admin-email@your-domain'

Default email address to use for various automated correspondence from the site managers, used for registration emails:

DEFAULT_FROM_EMAIL = 'your-admin-email@your-domain'

Initialize the Weblate database

Initialize the Weblate database, see syncdb:

cd /opt/weblate
sudo python ./manage.py syncdb

You will be prompted for the Django superuser password, provide one and take note.

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no):
Username (leave blank to use 'root'):
E-mail address: your-superuser-email@your-domain
Password: YOUR_DJANGO_ROOT_PASSWORD

Synchronize the database state with the current set of models and migrations:

cd /opt/weblate
sudo python ./manage.py migrate

Generate the Weblate localization files

cd /opt/weblate
sudo ./scripts/generate-locales

Setup the Weblate Apache Site

Create a new Apache site file:

sudo nano /etc/apache2/sites-available/weblate

Paste the following and adjust for your site, see Apache Core and modwsgi Configuration Directives:

#
# VirtualHost for weblate
#
<VirtualHost *:80>
  ServerName your-server-host-name
  ServerAdmin your-admin-user@your-domain

  DocumentRoot /opt/weblate/weblate/media/

  Alias /robots.txt /opt/weblate/weblate/media/robots.txt
  Alias /favicon.ico /opt/weblate/weblate/media/favicon.ico
  Alias /media/ /opt/weblate/weblate/media/
  Alias /doc/ /opt/weblate/weblate/html/
  Alias /static/admin /usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin/

  SetEnv HOME /var/opt/weblate

  WSGIDaemonProcess weblate user=weblate group=weblate processes=1 threads=15 home=/var/opt/weblate display-name=weblate python-path=/opt/weblate
  WSGIProcessGroup weblate

  <Directory /usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin/>
      Order deny,allow
      Allow from all
  </Directory>
  <Directory /opt/weblate/weblate/media/>
      Order deny,allow
      Allow from all
  </Directory>
  <Directory /opt/weblate/weblate/html/>
      Order deny,allow
      Allow from all
  </Directory>
  <Directory /opt/weblate/weblate/examples/>
      Order deny,allow
      Allow from all
  </Directory>

  WSGIScriptAlias / /opt/weblate/weblate/wsgi.py
  WSGIPassAuthorization On
  <Directory /opt/weblate/weblate>
      <Files wsgi.py>
      Order deny,allow
      Allow from all
      </Files>
  </Directory>
</VirtualHost>

Disable the default Apache site:

sudo a2dissite default

Enable the Weblate site:

sudo a2ensite weblate

Restart Apache:

sudo service apache2 restart

Access Weblate

At this point you should be able to access the Weblate administrative interface with a browser:

http://your-server-host-name/admin/

You can check if Weblate is configured properly visiting the Performace report:

http://your-server-host-name/admin/performance/

You can also configure the Weblate users and permissions:

http://your-server-host-name/admin/auth/user/

Program a CRON job for full-text indexing

As we specified the Weblate option OFFLOAD_INDEXING = True we will need to configure a CRON job to update the full-text index.

Start the crontab editor:

sudo -u weblate crontab -e

Add the following to the end of the file (update the index every 5 minutes):

*/5 * * * * /opt/weblate/manage.py update_index

Setup your Git repository SSH key

In order to access your Git repository you will need to provide the repository private SSH key.

From your local machine copy the Git repository private SSH key to the server machine:

scp -i your-machine-key-file.pem your-git-rsa-file ubuntu@your-machine-public-dns:/home/ubuntu/

Open a terminal on the remote machine:

ssh -i your-machine-key-file.pem ubuntu@your-machine-public-dns

Move the Git repository SSH key to the /var/opt/weblate/.ssh/ directory.

sudo mv your-git-rsa-file /var/opt/weblate/.ssh/

Set ownership.

sudo chown weblate:weblate /var/opt/weblate/.ssh/your-git-rsa-file

Configure the SSH host:

cd /var/opt/weblate/.ssh
sudo -u weblate nano config

For example, if your repository is hosted on Bitbucket, paste the following:

Host bitbucket.org
  User git
  Hostname bitbucket.org
  PreferredAuthentications publickey
  IdentityFile /var/opt/weblate/.ssh/your-git-rsa-file

For a Github hosted repository, paste the following:

Host github.com
  User git
  Hostname github.com
  PreferredAuthentications publickey
  IdentityFile /var/opt/weblate/.ssh/your-git-rsa-file

Set permissions:

sudo chmod 700 /var/opt/weblate/.ssh
sudo chmod 600 /var/opt/weblate/.ssh/config
sudo chmod 600 /var/opt/weblate/.ssh/your-git-rsa-file

Test the SSH connection and add to the list of known hosts.

If your repository is hosted on Bitbucket:

sudo -u weblate ssh -T git@bitbucket.org

If your repository is hosted on GitHub:

sudo -u weblate ssh -T git@github.com

You will be prompted for confirmation:

Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'your-git-host' (RSA) to the list of known hosts.
logged in as your-user-name

Configure the Weblate translation projects

At this point you should be able to configure a Weblate translation project and subproject, see Adding translation and Translation organization on the Weblate documentation.