Manual Installation

The following instructions describe the step-by-step process for installing Alaveteli. You don't necessarily need to do it this way: it's usually easier to use the installation script.

Note that there are other ways to install Alaveteli.

  • Commands in this guide will require root privileges
  • Commands are intended to be run via the terminal or over ssh

Configure the Operating System

Target operating system

These instructions assume a 64-bit version of Debian 7 (Wheezy) or 14.04 LTS (Trusty). Debian is the best supported deployment platform. We also have instructions for installing on MacOS.

Set the locale

Debian Wheezy

Follow the Debian guide for configuring the locale of the operating system.

Generate the locales you wish to make available. When the interactive screen asks you to pick a default locale, choose “None”, as the SSH session will provide the locale required.

dpkg-reconfigure locales

Start a new SSH session to use your SSH locale.

Ubuntu Trusty

Unset the default locale, as the SSH session should provide the locale required.

update-locale LC_ALL=

Start a new SSH session to use your SSH locale.

If you’re going to run the tests, you’ll need to have the en_GB and en_GB.UTF-8 locales installed.

locale-gen en_GB
locale-gen en_GB.UTF-8
update-locale

Update the OS

Update the Operating System with the latest packages

apt-get update -y
apt-get upgrade -y

sudo is not installed on Debian by default. Install it along with git (the version control tool we’ll use to get a copy of the Alaveteli code).

apt-get install -y sudo git-core

Prepare to install system dependencies using OS packages

These are packages that the software depends on: third-party software used to parse documents, host the site, and so on. There are also packages that contain headers necessary to compile some of the gem dependencies in the next step.

Using other repositories to get more recent packages

Add the following repositories to /etc/apt/sources.list:

Debian Wheezy

cat > /etc/apt/sources.list.d/debian-extra.list <<EOF
# Debian mirror to use, including contrib and non-free:
deb http://the.earth.li/debian/ wheezy main contrib non-free
deb-src http://the.earth.li/debian/ wheezy main contrib non-free

# Security Updates:
deb http://security.debian.org/ wheezy/updates main non-free
deb-src http://security.debian.org/ wheezy/updates main non-free
EOF

Packages customised by mySociety

If you’re using Debian or Ubuntu, you should add the mySociety Debian archive to your apt sources. Note that mySociety packages are currently only built for 64-bit Debian.

Debian Wheezy

cat > /etc/apt/sources.list.d/mysociety-debian.list <<EOF
deb http://debian.mysociety.org squeeze main
EOF

The repository above lets you install wkhtmltopdf-static using apt.

Add the GPG key from the mySociety Debian Package Repository.

wget -O - https://debian.mysociety.org/debian.mysociety.org.gpg.key | apt-key add -

You should also configure package-pinning to reduce the priority of the mysociety Debian repository - we only want to pull wkhtmltopdf-static from mysociety.

cat >> /etc/apt/preferences <<EOF

Package: *
Pin: origin debian.mysociety.org
Pin-Priority: 50
EOF

Other platforms

If you’re using some other linux platform, you can optionally install these dependencies manually, as follows:

  1. If you would like users to be able to get pretty PDFs as part of the downloadable zipfile of their request history, install wkhtmltopdf. We recommend downloading the latest, statically compiled version from the project website, as this allows running headless (that is, without a graphical interface running) on Linux. If you do install wkhtmltopdf, you need to edit a setting in the config file to point to it (see below). If you don’t install it, everything will still work, but users will get ugly, plain text versions of their requests when they download them.

  2. Version 1.44 of pdftk contains a bug which makes it loop forever in certain edge conditions. This is fixed in the standard 1.44.7 package which is available in wheezy (Debian) and raring (Ubuntu).

If you can’t get an official release for your OS with the fix, you can either hope you don’t encounter the bug (it ties up a rails process until you kill it), patch it yourself, or use the Debian or Ubuntu packages compiled by mySociety.

Refresh sources

Refresh the sources after adding the extra repositories:

apt-get -y update

Create Alaveteli User

Create a new linux user to run the Alaveteli application. Add them to the ‘adm’ group so that they can read the mail log files.

adduser --quiet --disabled-password --gecos "Alaveteli" alaveteli
usermod -a -G adm alaveteli

Get Alaveteli

Create the target directory and clone the Alaveteli source code in to this directory:

mkdir -p /var/www/alaveteli
chown alaveteli:alaveteli /var/www
chown alaveteli:alaveteli /var/www/alaveteli
cd /home/alaveteli
sudo -u alaveteli git clone --recursive \
  --branch master \
  https://github.com/mysociety/alaveteli.git /var/www/alaveteli

This clones the master branch which always contains the latest stable release. If you want to try out the latest (possibly buggy) code you can switch to the develop branch.

pushd /var/www/alaveteli
sudo -u alaveteli git checkout develop
sudo -u alaveteli git submodule update
popd

The --recursive option installs mySociety’s common libraries which are required to run Alaveteli.

Install the dependencies

Now install the packages relevant to your system:

# Debian Wheezy
apt-get -y install $(cat /var/www/alaveteli/config/packages.debian-wheezy)

Some of the files also have a version number listed in config/packages - check that you have appropriate versions installed. Some also list “|” and offer a choice of packages.

Note: To install Alaveteli's Ruby dependencies, you need to install bundler. In Debian and Ubuntu, this is provided as a package (installed as part of the package install process above). For other OSes, you could also install it as a gem:
sudo -u alaveteli gem install --user-install bundler --no-rdoc --no-ri
You should see a warning telling you that gem executables will not run as the application user doesn't have their local gem bin path in their path. Add it, making sure you use the ruby version directory you see in the warning message:
cat >> /home/alaveteli/.bashrc <<EOF
export PATH="\$HOME/.gem/ruby/1.9.1/bin:\$PATH"
EOF
exec $SHELL

Configure Database

There has been a little work done in trying to make the code work with other databases (e.g., SQLite), but the currently supported database is PostgreSQL (“postgres”).

Create a foi user from the command line, like this:

sudo -u postgres createuser -s -P foi

Note: Leaving the password blank will cause great confusion if you’re new to PostgreSQL.

We’ll create a template for our Alaveteli databases:

sudo -u postgres createdb -T template0 -E UTF-8 template_utf8
echo "update pg_database set datistemplate=true where datname='template_utf8';" > /tmp/update-template.sql
sudo -u postgres psql -f /tmp/update-template.sql
rm /tmp/update-template.sql

Then create the databases:

sudo -u postgres createdb -T template_utf8 -O foi alaveteli_production
sudo -u postgres createdb -T template_utf8 -O foi alaveteli_test
sudo -u postgres createdb -T template_utf8 -O foi alaveteli_development

Configure email

You will need to set up an email server – or Mail Transfer Agent (MTA) – to send and receive emails.

Full configuration for an MTA is beyond the scope of this document – see the guide for configuring the Exim4 or Postfix MTAs.

Note that in development mode mail is handled by mailcatcher by default so that you can see the mails in a browser. Start mailcatcher by running bundle exec mailcatcher in the application directory.

Configure Alaveteli

Alaveteli has three main configuration files:

  • config/database.yml: Configures Alaveteli to communicate with the database
  • config/general.yml: The general Alaveteli application settings

Copy the configuration files and update their permissions:

cp /var/www/alaveteli/config/database.yml-example /var/www/alaveteli/config/database.yml
cp /var/www/alaveteli/config/general.yml-example /var/www/alaveteli/config/general.yml
chown alaveteli:alaveteli /var/www/alaveteli/config/{database,general}.yml
chmod 640 /var/www/alaveteli/config/{database,general}.yml

database.yml

Now you need to set up the database config file so that the application can connect to the postgres database.

Edit each section to point to the relevant local postgresql database.

Example development section of config/database.yml:

development:
  adapter: postgresql
  template: template_utf8
  database: alaveteli_development
  username: foi
  password: secure-password-here
  host: localhost
  port: 5432

Make sure that the user specified in database.yml exists, and has full permissions on these databases.

As the user needs the ability to turn off constraints whilst running the tests they also need to be a superuser (clarification: a Postgres superuser, not an Alaveteli admin). If you don’t want your database user to be a superuser, you can add this line to the test section in database.yml (as seen in config/database.yml-example):

constraint_disabling: false

general.yml

We have a full guide to Alaveteli configuration which covers all the settings in config/general.yml.

Note: If you are setting up Alaveteli to run in production, set the STAGING_SITE variable to 0 in /var/www/alaveteli/config/general.yml now.

STAGING_SITE: 0

The default settings for frontpage examples are designed to work with the dummy data shipped with Alaveteli; once you have real data, you should certainly edit these.

The default theme is the “Alaveteli” theme. When you run rails-post-deploy (see below), that theme gets installed automatically.

Deployment

You should run the rails-post-deploy script after each new software upgrade:

sudo -u alaveteli RAILS_ENV=production \
  /var/www/alaveteli/script/rails-post-deploy

This installs Ruby dependencies, installs/updates themes, runs database migrations, updates shared directories and runs other tasks that need to be run after a software update, like precompiling static assets for a production install.

That the first time you run this script can take a long time, as it must compile native dependencies for xapian-full.

Create the index for the search engine (Xapian):

sudo -u alaveteli RAILS_ENV=production \
  /var/www/alaveteli/script/rebuild-xapian-index

If this fails, the site should still mostly run, but it’s a core component so you should really try to get this working.

Note that we set RAILS_ENV=production. Use RAILS_ENV=development if you are installing Alaveteli to make changes to the code.

Configure the Application Server

Alaveteli can run under many popular application servers. mySociety recommends the use of Phusion Passenger (AKA mod_rails) or thin.

Using Phusion Passenger

Passenger is the recommended application server as it is well proven in production environments. It is implemented as an Apache mod, so it cannot be run independently.

apt-get install -y libapache2-mod-passenger

See later in the guide for configuring the Apache web server with Passenger.

Using Thin

Thin is a lighter-weight application server which can be run independently of a web server. Thin will be installed in the application bundle and used to run Alaveteli by default.

Run the following to get the server running:

cd /var/www/alaveteli
bundle exec thin \
  --environment=production \
  --user=alaveteli \
  --group=alaveteli \
  --servers=1 \
  start

By default the server listens on all interfaces. You can restrict it to the localhost interface by adding --address=127.0.0.1

The server should have told you the URL to access in your browser to see the site in action.

You can daemonize the process by starting it with the --daemonize option.

Next we’ll actually create a SysVinit daemon to run the application, so stop any thin processes you’ve started here.

Cron jobs and Daemons

Now is a good time to configure the cron jobs and daemons required for the application to run.

Configure the web server

In almost all scenarios, we recommend running the Alaveteli Rails application behind a web server. This allows the web server to serve static content without going through the Rails stack, which improves performance.

We recommend two main combinations of application and web server:

  • Apache & Passenger
  • Nginx & Thin

There are ways to run Passenger with Nginx, and indeed Thin with Apache, but that’s out of scope for this guide. If you want to do something that isn’t documented here, get in touch on alaveteli-dev and we’ll be more than happy to help you get set up.

You should have already installed an application server if you have followed this guide, so pick the appropriate web server to configure.

Apache (with Passenger)

Install Apache with the Suexec wrapper:

apt-get install -y apache2
apt-get install -y apache2-suexec

Enable the required modules

a2enmod actions
a2enmod expires
a2enmod headers
a2enmod passenger
a2enmod proxy
a2enmod proxy_http
a2enmod rewrite
a2enmod suexec

Create a directory for optional Alaveteli configuration

mkdir -p /etc/apache2/vhost.d/alaveteli

Copy the example VirtualHost configuration file. You will need to change all occurrences of www.example.com to your URL

Debian Wheezy

cp /var/www/alaveteli/config/httpd.conf-example \
  /etc/apache2/sites-available/alaveteli

Ubuntu Trusty

cp /var/www/alaveteli/config/httpd.conf-example \
  /etc/apache2/sites-available/alaveteli.conf

Disable the default site and enable the alaveteli VirtualHost

Debian Wheezy

a2dissite default
a2ensite alaveteli

Ubuntu Trusty

a2dissite 000-default.conf
a2ensite alaveteli.conf

Check the configuration and fix any issues

apachectl configtest

Restart apache to load the new Alaveteli config

service apache2 graceful

It’s strongly recommended that you run the site over SSL. (Set FORCE_SSL to true in config/general.yml). For this you will need an SSL certificate for your domain.

Enable the SSL apache mod

a2enmod ssl

Copy the SSL configuration – again changing www.example.com to your domain – and enable the VirtualHost

Debian Wheezy

cp /var/www/alaveteli/config/httpd-ssl.conf.example \
  /etc/apache2/sites-available/alaveteli_https
a2ensite alaveteli_https

Ubuntu Trusty

cp /var/www/alaveteli/config/httpd-ssl.conf.example \
  /etc/apache2/sites-available/alaveteli_https.conf
a2ensite alaveteli_https.conf

Force HTTPS requests from the HTTP VirtualHost

cp /var/www/alaveteli/config/httpd-force-ssl.conf.example \
  /etc/apache2/vhost.d/alaveteli/force-ssl.conf

If you are testing Alaveteli or setting up an internal staging site, generate self-signed SSL certificates. Do not use self-signed certificates for a production server. Replace www.example.com with your domain name.

openssl genrsa -out /etc/ssl/private/www.example.com.key 2048
chmod 640 /etc/ssl/private/www.example.com.key

openssl req -new -x509 \
  -key /etc/ssl/private/www.example.com.key \
  -out /etc/ssl/certs/www.example.com.cert \
  -days 3650 \
  -subj /CN=www.example.com
chmod 640 /etc/ssl/certs/www.example.com.cert

Check the configuration and fix any issues

apachectl configtest

Restart apache to load the new Alaveteli config. This will also restart Passenger (the application server).

service apache2 graceful

Nginx (with Thin)

Install nginx

apt-get install -y nginx

Running over SSL

It’s strongly recommended that you run the site over SSL. (Set FORCE_SSL to true in config/general.yml). For this you will need an SSL certificate for your domain.

Copy the SSL configuration – changing www.example.com to your domain – and enable the alaveteli_https server, disabling the default site.

cp /var/www/alaveteli/config/nginx-ssl.conf.example \
  /etc/nginx/sites-available/alaveteli_https
rm /etc/nginx/sites-enabled/default
ln -s /etc/nginx/sites-available/alaveteli_https \
  /etc/nginx/sites-enabled/alaveteli_https
Note: For historical reasons, nginx-ssl.conf.example has the path to Alaveteli set as /var/www/alaveteli/alaveteli – you will need to manually change this to /var/www/alaveteli, or to the root of your Alaveteli install

If you are testing Alaveteli or setting up an internal staging site, generate self-signed SSL certificates. Do not use self-signed certificates for a production server. Replace www.example.com with your domain name.

openssl genrsa -out /etc/ssl/private/www.example.com.key 2048
chmod 640 /etc/ssl/private/www.example.com.key

openssl req -new -x509 \
  -key /etc/ssl/private/www.example.com.key \
  -out /etc/ssl/certs/www.example.com.cert \
  -days 3650 \
  -subj /CN=www.example.com
chmod 640 /etc/ssl/certs/www.example.com.cert

If you have configured thin to use more than one server, you will need to edit the Alaveteli upstream directive in your /etc/nginx/sites-enabled/alaveteli_https file so that it has a server line for each instance you are running (otherwise nginx will only know how to send requests to the first server process). Each address line needs to have a unique port number - start at 3000 and add 1 for each new process. For example if you started your cluster with 4 servers, the upstream directive should look like this:

upstream alaveteli {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;
}

Check the configuration and fix any issues

service nginx configtest

Reload the new nginx configuration and restart the application

service nginx reload
service alaveteli restart

Running without SSL

Set FORCE_SSL to false in config/general.yml. Copy the example nginx config

cp /var/www/alaveteli/config/nginx.conf.example \
  /etc/nginx/sites-available/alaveteli
Note: For historical reasons, nginx.conf.example has the path to Alaveteli set as /var/www/alaveteli/alaveteli – you will need to manually change this to /var/www/alaveteli, or to the root of your Alaveteli install

Disable the default site and enable the alaveteli server

rm /etc/nginx/sites-enabled/default
ln -s /etc/nginx/sites-available/alaveteli \
  /etc/nginx/sites-enabled/alaveteli

If you have configured thin to use more than one server, you will need to edit the Alaveteli upstream directive in your /etc/nginx/sites-enabled/alaveteli file so that it has a server line for each instance you are running (otherwise nginx will only know how to send requests to the first server process). Each address line needs to have a unique port number - start at 3000 and add 1 for each new process. For example if you started your cluster with 4 servers, the upstream directive should look like this:

upstream alaveteli {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;
}

Check the configuration and fix any issues

service nginx configtest

Start the rails application with thin (if you haven’t already).

service alaveteli start

Reload the nginx configuration

service nginx reload

Add varnish as an HTTP accelerator

Under all but light loads, it is strongly recommended to run the server behind an http accelerator like Varnish. A sample varnish VCL is supplied in conf/varnish-alaveteli.vcl.

If you are using SSL you will need to configure an SSL terminator to sit in front of Varnish. If you’re already using Apache as a web server you could simply use Apache as the SSL terminator.

We have some production server best practice notes.

What next?

Check out the next steps.

Troubleshooting

  • Run the Tests

    Make sure everything looks OK. As the alaveteli user, run:

    bundle exec rake spec
    

    If there are failures here, something has gone wrong with the preceding steps (see the next section for a common problem and workaround). You might be able to move on to the next steps, depending on how serious they are, but ideally you should try to find out what’s gone wrong.

Note: If you have setup your install of Alaveteli for production, you will need to temporarily remove the file config/rails_env.rb, which is used to force the rails environment to production, and edit your .bundle/config file to remove the BUNDLE_WITHOUT line that excludes development dependencies. After you have done this, as the alaveteli user, run bundle install. You will also need to make alaveteli the owner of /var/www/alaveteli/log/development.log, and run the database migrations.
chown alaveteli:alaveteli /var/www/alaveteli/log/development.log
sudo -u alaveteli bundle exec rake db:migrate
You should then be able to run the tests. Don't forget to restore config/rails_env.rb when you're done. You will probably see some errors from cron jobs in the meantime, as they'll be running in development mode.
  • When running tests, I see a failure with “PG::UndefinedObject: ERROR: collation “en_GB” for encoding “UTF8” does not exist”

    You can install the “en_GB” collation manually:

    psql -c 'CREATE COLLATION "en_GB" (LOCALE = "en_GB.utf8");' -U postgres alaveteli_test
    
  • Incoming emails aren’t appearing in my Alaveteli install

    See the general email troubleshooting guide.

  • Various tests fail with “Your PostgreSQL connection does not support unescape_bytea. Try upgrading to pg 0.9.0 or later.”

    You have an old version of pg, the ruby postgres driver. In Ubuntu, for example, this is provided by the package libdbd-pg-ruby.

    Try upgrading your system’s pg installation, or installing the pg gem with gem install pg

  • Some of the tests relating to mail are failing, with messages like “when using TMail should load an email with funny MIME settings’ FAILED”

    This sounds like the tests are running using the production environment, rather than the test environment, for some reason.

  • Non-ASCII characters are being displayed as asterisks in my incoming messages

    We rely on elinks to convert HTML email to plain text. Normally, the encoding should just work, but under some circumstances it appears that elinks ignores the parameters passed to it from Alaveteli.

    To force elinks always to treat input as UTF8, add the following to /etc/elinks/elinks.conf:

    set document.codepage.assume = "utf-8"
    set document.codepage.force_assumed = 1
    

    You should also check that your locale is set up correctly. See this issue followup for further discussion.

  • I’m seeing rake: command not found when running the post install script

    The script uses rake.

    It may be that the binaries installed by bundler are not put in the system PATH; therefore, in order to run rake (needed for deployments), you may need to do something like:

    ln -s /usr/lib/ruby/gems/1.8/bin/rake /usr/local/bin/