diff options
author | Martin Wright <martin@mynameismartin.com> | 2015-04-07 14:46:11 +0100 |
---|---|---|
committer | Martin Wright <martin@mynameismartin.com> | 2015-04-07 14:46:11 +0100 |
commit | 270606788ba97b9c509183a06cdefe3b83f07464 (patch) | |
tree | 3304ea68b1e5cfecc2518aa6effa643175e12fdd /docs/installing/manual_install.md | |
parent | 970396737e03ec2336f0ecc34d07047d83ff2629 (diff) | |
parent | 6cc59ede7bca866f7e56c771cc12ca1afa9406ef (diff) |
Merge branch 'gh-pages' of ssh://git.mysociety.org/data/git/public/alaveteli into gh-pages
Diffstat (limited to 'docs/installing/manual_install.md')
-rw-r--r-- | docs/installing/manual_install.md | 924 |
1 files changed, 640 insertions, 284 deletions
diff --git a/docs/installing/manual_install.md b/docs/installing/manual_install.md index 777d95139..9cad6b5b9 100644 --- a/docs/installing/manual_install.md +++ b/docs/installing/manual_install.md @@ -17,91 +17,183 @@ title: Manual installation Note that there are [other ways to install Alaveteli]({{ site.baseurl }}docs/installing/). -## Target operating system +<div class="attention-box"> + <ul> + <li>Commands in this guide will require root privileges</li> + <li>Commands are intended to be run via the terminal or over ssh</li> + </ul> +</div> -These instructions assume Debian Squeeze (64-bit) or Ubuntu 12.04 LTS -(precise). Debian Squeeze is the best supported deployment platform. We also +## Configure the Operating System + +### Target operating system + +These instructions assume a 64-bit version of Debian 6 (Wheezy), Debian 7 (Squeeze) +or Ubuntu 12.04 LTS (Precise). Debian is the best supported deployment platform. We also have instructions for [installing on MacOS]({{ site.baseurl }}docs/installing/macos/). -Commands are intended to be run via the terminal or over ssh. +### Set the locale +**Debian Wheezy or Squeeze** -## Get Alaveteli +Follow the [Debian guide](https://wiki.debian.org/Locale#Standard) 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. -To start with, you may need to install git, e.g. with `sudo apt-get install -git-core` + dpkg-reconfigure locales + +Start a new SSH session to use your SSH locale. + +**Ubuntu Precise** -Next, get hold of the Alaveteli source code from github: +Unset the default locale, as the SSH session should provide the locale required. - git clone https://github.com/mysociety/alaveteli.git - cd alaveteli + update-locale LC_ALL= -This will get the rails-3-develop branch, which has the latest (possibly buggy) -code. If you don't want to add or try new features, swap to the master branch -(which always contains the latest stable release): +Start a new SSH session to use your SSH locale. - git checkout master +### Update the OS -## Install mySociety libraries +Update the Operating System with the latest packages -Next, install mySociety's common ruby libraries. To fetch the contents of the -submodules, run: + apt-get update -y + apt-get upgrade -y - git submodule update --init +`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). -## Install system dependencies + 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 Squeeze** - cat > /etc/apt/sources.list.d/debian-backports.list <<EOF + 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/ squeeze main contrib non-free + deb-src http://the.earth.li/debian/ squeeze main contrib non-free + + # Security Updates: + deb http://security.debian.org/ squeeze/updates main non-free + deb-src http://security.debian.org/ squeeze/updates main non-free + + # Debian Backports deb http://backports.debian.org/debian-backports squeeze-backports main contrib non-free + deb-src http://backports.debian.org/debian-backports squeeze-backports main contrib non-free + + # Wheezy + deb http://ftp.uk.debian.org/debian wheezy main contrib non-free + EOF + +The squeeze-backports repository is providing a more recent version of rubygems, and the wheezy repository is providing bundler. You should configure package-pinning to reduce the priority of the wheezy repository so other packages aren't pulled from it. + + cat >> /etc/apt/preferences <<EOF + + Package: bundler + Pin: release n=wheezy + Pin-Priority: 990 + + Package: * + Pin: release n=wheezy + Pin-Priority: 50 EOF -The repositories above let you install `wkhtmltopdf-static` and `bundler` using -`apt`. +**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 **Ubuntu Precise** cat > /etc/apt/sources.list.d/ubuntu-extra.list <<EOF - deb http://eu-west-1.ec2.archive.ubuntu.com/ubuntu/ precise multiverse - deb-src http://eu-west-1.ec2.archive.ubuntu.com/ubuntu/ precise multiverse - deb http://eu-west-1.ec2.archive.ubuntu.com/ubuntu/ precise-updates multiverse - deb-src http://eu-west-1.ec2.archive.ubuntu.com/ubuntu/ precise-updates multiverse + deb http://de.archive.ubuntu.com/ubuntu/ precise multiverse + deb-src http://de.archive.ubuntu.com/ubuntu/ precise multiverse + deb http://de.archive.ubuntu.com/ubuntu/ precise-updates multiverse + deb-src http://de.archive.ubuntu.com/ubuntu/ precise-updates multiverse + deb http://de.archive.ubuntu.com/ubuntu/ trusty universe + deb-src http://de.archive.ubuntu.com/ubuntu/ trusty universe EOF -The repositories above let you install `wkhtmltopdf-static` using `apt`. -`bundler` will have to be installed manually on Ubuntu Precise. +The trusty repo is used here to get a more recent version of bundler. You should configure package-pinning to reduce the priority of the trusty repository so other packages aren't pulled from it. + + cat >> /etc/apt/preferences <<EOF -### Packages customised by mySociety + Package: ruby-bundler + Pin: release n=trusty + Pin-Priority: 990 -If you're using Debian, you should add the mySociety Debian archive to your + Package: * + Pin: release n=trusty + Pin-Priority: 50 + 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 Squeeze, Wheezy or Ubuntu Precise** + 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` and `pdftk` (for squeeze) using `apt`. + Add the GPG key from the [mySociety Debian Package Repository](http://debian.mysociety.org/). - wget -O - https://debian.mysociety.org/debian.mysociety.org.gpg.key | sudo apt-key add - + wget -O - https://debian.mysociety.org/debian.mysociety.org.gpg.key | apt-key add - + +**Ubuntu Precise only** + + cat > /etc/apt/sources.list.d/mysociety-launchpad.list <<EOF + deb http://ppa.launchpad.net/mysociety/alaveteli/ubuntu precise main + deb-src http://ppa.launchpad.net/mysociety/alaveteli/ubuntu precise main + EOF + +The repository above lets you install a recent version of `pdftk` using `apt`. + +Add the GPG key from the +[mySociety Alaveteli Ubuntu Package Repository](https://launchpad.net/~mysociety/+archive/ubuntu/alaveteli). + + apt-get install -y python-software-properties + add-apt-repository -y ppa:mysociety/alaveteli + +**Debian Wheezy or Ubuntu Precise** -You should also configure package-pinning to reduce the priority of this -repository. +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 - cat > /etc/apt/preferences <<EOF Package: * Pin: origin debian.mysociety.org Pin-Priority: 50 EOF -If you're using some other platform, you can optionally install these +**Debian Squeeze** + +No special package pinning is required. + +#### 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 @@ -115,37 +207,76 @@ 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. Until it's incorporated into an official release, 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 package -compiled by mySociety (see link in [issue -305](https://github.com/mysociety/alaveteli/issues/305)) +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](http://debian.mysociety.org/dists/squeeze/main/binary-amd64/) +or +[Ubuntu](https://launchpad.net/~mysociety/+archive/ubuntu/alaveteli/+packages) +packages compiled by mySociety. -### Install the dependencies +#### Refresh sources Refresh the sources after adding the extra repositories: - sudo apt-get update + apt-get -y update + +### Create Alaveteli User + +Create a new linux user to run the Alaveteli application. + + adduser --quiet --disabled-password --gecos "Alaveteli" 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 `rails-3-develop` branch. + + pushd /var/www/alaveteli + sudo -u alaveteli git checkout rails-3-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) + # Debian Squeeze - sudo apt-get install $(cat config/packages.debian-squeeze) + apt-get -y install $(cat /var/www/alaveteli/config/packages.debian-squeeze) # Ubuntu Precise - sudo apt-get install $(cat config/packages.ubuntu-precise) + apt-get -y install $(cat /var/www/alaveteli/config/packages.ubuntu-precise) 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. -## Install Ruby dependencies +<div class="attention-box"> + +<strong>Note:</strong> 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: + + <pre><code> gem install bundler --no-rdoc --no-ri</code></pre> -To install Alaveteli's Ruby dependencies, you need to install bundler. In -Debian, this is provided as a package (installed as part of the package install -process above). You could also install it as a gem: +</div> - sudo gem install bundler ## Configure Database @@ -153,348 +284,573 @@ 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"). -If you don't have postgres installed: - - $ sudo apt-get install postgresql postgresql-client - Create a `foi` user from the command line, like this: - # sudo -u postgres createuser -s -P foi + 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 template0 -E SQL_ASCII -O foi foi_production - # sudo -u postgres createdb -T template0 -E SQL_ASCII -O foi foi_test - # sudo -u postgres createdb -T template0 -E SQL_ASCII -O foi foi_development + 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]({{ site.baseurl }}docs/installing/email/). + +Note that in development mode mail is handled by [`mailcatcher`](http://mailcatcher.me/) 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 + - `config/newrelic.yml`: Configuration for the [NewRelic](http://newrelic.com) monitoring service + +Copy the configuration files and update their permissions: -We create using the ``SQL_ASCII`` encoding, because in postgres this is means -"no encoding"; and because we handle and store all kinds of data that may not -be valid UTF (for example, data originating from various broken email clients -that's not 8-bit clean), it's safer to be able to store *anything*, than reject -data at runtime. + 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 + cp /var/www/alaveteli/config/newrelic.yml-example /var/www/alaveteli/config/newrelic.yml + chown alaveteli:alaveteli /var/www/alaveteli/config/{database,general,newrelic}.yml + chmod 640 /var/www/alaveteli/config/{database,general,newrelic}.yml -Now you need to set up the database config file to contain the name, username -and password of your postgres database. +### database.yml -* Copy `database.yml-example` to `database.yml` in `alaveteli/config` -* Edit it to point to your local postgresql database in the development - and test sections. +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 - database: foi_development + 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 they need the ability to turn off -constraints whilst running the tests they also need to be a superuser +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 <em>Postgres</em> superuser, +not an Alaveteli +<a href="{{ site.baseurl }}docs/glossary/#super" class="glossary__link">superuser</a>). If you don't want your database user to be a superuser, you can add this line -to the test config in `database.yml` (as seen in `database.yml-example`) +to the `test` section in `database.yml` (as seen in `config/database.yml-example`): constraint_disabling: false -## Configure email +### general.yml -You will need to set up an email server (MTA) to send and receive emails. Full -configuration for an MTA is beyond the scope of this document -- see this -[example config for Exim4]({{ site.baseurl }}docs/installing/email/). +We have a full [guide to Alaveteli configuration]({{ site.baseurl }}docs/customising/config/) which covers all the settings in `config/general.yml`. -Note that in development mode mail is handled by mailcatcher by default so -that you can see the mails in a browser - see [http://mailcatcher.me/](http://mailcatcher.me/) for more -details. Start mailcatcher by running `bundle exec mailcatcher` in your -application directory. +_Note:_ If you are setting up Alaveteli to run in production, set the [`STAGING_SITE`]({{ site.baseurl }}docs/customising/config/#staging_site) variable to `0` in `/var/www/alaveteli/config/general.yml` now. -### Minimal + STAGING_SITE: 0 -If you just want to get the tests to pass, you will at a minimum need to allow -sending emails via a `sendmail` command (a requirement met, for example, with -`sudo apt-get install exim4`). +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. -### Detailed +The default theme is the ["Alaveteli" theme](https://github.com/mysociety/alavetelitheme). When you run `rails-post-deploy` (see below), that theme gets installed automatically. -When an authority receives an email, the email's `reply-to` field is a magic -address which is parsed and consumed by the Rails app. +### newrelic.yml -To receive such email in a production setup, you will need to configure your -MTA to pipe incoming emails to the Alaveteli script `script/mailin`. Therefore, -you will need to configure your MTA to accept emails to magic addresses, and to -pipe such emails to this script. +This file contains configuration information for the New Relic performance +management system. By default, monitoring is switched off by the +`agent_enabled: false` setting. See New Relic's [remote performance analysis](https://github.com/newrelic/rpm) instructions for switching it on +for both local and remote analysis. -Magic email addresses are of the form: +## Deployment - <foi+request-3-691c8388@example.com> +You should run the `rails-post-deploy` script after each new software upgrade: -The respective parts of this address are controlled with options in -`config/general.yml`, thus: + sudo -u alaveteli RAILS_ENV=production \ + /var/www/alaveteli/script/rails-post-deploy - INCOMING_EMAIL_PREFIX = 'foi+' - INCOMING_EMAIL_DOMAIN = 'example.com' +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. -When you set up your MTA, if there is some error inside Rails, the -email is returned with an exit code 75, which for Exim at least means the MTA -will try again later. Additionally, a stacktrace is emailed to `CONTACT_EMAIL`. +That the first time you run this script can take a *long* time, as it must +compile native dependencies for `xapian-full`. -See [this example]({{ site.baseurl }}docs/installing/email/) for a possible configuration for Exim (>=1.9). +Create the index for the search engine (Xapian): -A well-configured installation of this code will have had Exim make -a backup copy of the email in a separate mailbox, just in case. + sudo -u alaveteli RAILS_ENV=production \ + /var/www/alaveteli/script/rebuild-xapian-index -## Set up configs +If this fails, the site should still mostly run, but it's a core component so +you should really try to get this working. -Copy `config/general.yml-example` to `config/general.yml` and edit to your -taste. +<div class="attention-box"> + Note that we set <code>RAILS_ENV=production</code>. Use + <code>RAILS_ENV=development</code> if you are installing Alaveteli to make + changes to the code. +</div> -Note that 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. +## Configure the Application Server -The default theme is the "Alaveteli" theme. When you run `rails-post-deploy` -(see below), that theme gets installed automatically. +Alaveteli can run under many popular application servers. mySociety recommends +the use of [Phusion Passenger](https://www.phusionpassenger.com) (AKA +mod_rails) or [thin](http://code.macournoyer.com/thin). -Finally, copy `config/newrelic.yml-example` to `config/newrelic.yml`. This file -contains configuration information for the New Relic performance management -system. By default, monitoring is switched off by the `agent_enabled: false` -setting. See New Relic's [remote performance analysis](https://github.com/newrelic/rpm) instructions for switching it on -for both local and remote analysis. +### 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. -## Deployment + apt-get install -y libapache2-mod-passenger -In the `alaveteli` directory, run: +See later in the guide for configuring the Apache web server with Passenger. - script/rails-post-deploy +### Using Thin -(This will need execute privs so `chmod 755` if necessary.) This sets up -directory structures, creates logs, installs/updates themes, runs database -migrations, etc. You should run it after each new software update. +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. -One of the things the script does is install dependencies (using `bundle -install`). Note that the first time you run it, part of the `bundle install` -that compiles `xapian-full` takes a *long* time! +Run the following to get the server running: -If you want some dummy data to play with, you can try loading the fixtures that -the test suite uses into your development database. You can do this with: + cd /var/www/alaveteli + bundle exec thin \ + --environment=production \ + --user=alaveteli \ + --group=alaveteli \ + start - script/load-sample-data +By default the server listens on all interfaces. You can restrict it to the +localhost interface by adding `--address=127.0.0.1` -Next, create the index for the search engine (Xapian): +The server should have told you the URL to access in your browser to see the +site in action. - script/rebuild-xapian-index +You can daemonize the process by starting it with the `--daemonize` option. -If this fails, the site should still mostly run, but it's a core component so -you should really try to get this working. +Later in this guide we'll actually create a SysVinit daemon to run the application, so stop any thin processes you've started here. -## Run the Tests +## Cron jobs and Daemons -Make sure everything looks OK: +The crontab and init scripts use the `.ugly` file format, which is a strange +templating format used by mySociety. - bundle exec rake spec +The `ugly` format uses simple variable substitution. A variable looks like +`!!(*= $this *)!!`. -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 step, depending on how serious they are, but ideally you -should try to find out what's gone wrong. +### Generate crontab -### glibc bug workaround +`config/crontab-example` contains the cron jobs that run on +Alaveteli. Rewrite the example file to replace the variables, +and then drop it in `/etc/cron.d/` on the server. -There's a [bug in -glibc](http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=637239) which causes -Xapian to segfault when running the tests. Although the bug report linked to -claims it's fixed in the current Debian stable, it's not as of version -`2.11.3-2`. +**Template Variables:** -Until it's fixed (e.g. `libc6 2.13-26` does work), you can get the tests to -pass by setting `export LD_PRELOAD=/lib/libuuid.so.1`. +* `vhost_dir`: the full path to the directory where alaveteli is checked out. + e.g. If your checkout is at `/var/www/alaveteli` then set this to `/var/www` +* `vcspath`: the name of the directory that contains the alaveteli code. + e.g. `alaveteli` +* `user`: the user that the software runs as +* `site`: a string to identify your alaveteli instance +* `mailto`: The email address or local account that cron output will be sent to - setting an email address depends on your MTA having been configured for remote delivery. -## Run the Server +There is a rake task that will help to rewrite this file into one that is +useful to you. This example sends cron output to the local `alaveteli` user. Change the variables to suit your installation. -Run the following to get the server running: + pushd /var/www/alaveteli + bundle exec rake config_files:convert_crontab \ + DEPLOY_USER=alaveteli \ + VHOST_DIR=/var/www \ + VCSPATH=alaveteli \ + SITE=alaveteli \ + MAILTO=alaveteli \ + CRONTAB=/var/www/alaveteli/config/crontab-example > /etc/cron.d/alaveteli + popd - bundle exec rails server --environment=development + chown root:alaveteli /etc/cron.d/alaveteli + chmod 754 /etc/cron.d/alaveteli -By default the server listens on all interfaces. You can restrict it to the -localhost interface by adding `--binding=127.0.0.1` +### Generate application daemon -The server should have told you the URL to access in your browser to see the -site in action. +Generate a daemon based on the application server you installed. This allows you +to use the native `service` command to stop, start and restart the application. -## Administrator privileges +#### Passenger -The administrative interface is at the URL `/admin`. +**Template Variables:** -Only users with the `super` admin level can access the admin interface. Users -create their own accounts in the usual way, and then administrators can give -them `super` privileges. +* `vhost_dir`: the full path to the directory where alaveteli is checked out. + e.g. If your checkout is at `/var/www/alaveteli` then set this to `/var/www` +* `vcspath`: the name of the directory that contains the alaveteli code. + e.g. `alaveteli` +* `site`: a string to identify your alaveteli instance +* `user`: the user that the software runs as -There is an emergency user account which can be accessed via -`/admin?emergency=1`, using the credentials `ADMIN_USERNAME` and -`ADMIN_PASSWORD`, which are set in `general.yml`. To bootstrap the -first `super` level accounts, you will need to log in as the emergency -user. You can disable the emergency user account by setting `DISABLE_EMERGENCY_USER` to `true` in `general.yml`. +There is a rake task that will help to rewrite this file into one that is +useful to you. Change the variables to suit your installation. -Users with the superuser role also have extra privileges in the website -frontend, such as being able to categorise any request, being able to view -items that have been hidden from the search, and being presented with "admin" -links next to individual requests and comments in the front end. + pushd /var/www/alaveteli + bundle exec rake config_files:convert_init_script \ + DEPLOY_USER=alaveteli \ + VHOST_DIR=/var/www \ + VCSPATH=alaveteli \ + SITE=alaveteli \ + SCRIPT_FILE=/var/www/alaveteli/config/sysvinit-passenger.ugly > /etc/init.d/alaveteli + popd -It is possible completely to override the administrator authentication by -setting `SKIP_ADMIN_AUTH` to `true` in `general.yml`. + chown root:alaveteli /etc/init.d/alaveteli + chmod 754 /etc/init.d/alaveteli -## Cron jobs and init scripts +Start the application: -`config/crontab-example` contains the cronjobs run on WhatDoTheyKnow. It's in a -strange templating format they use in mySociety. mySociety render the example -file to reference absolute paths, and then drop it in `/etc/cron.d/` on the -server. + service alaveteli start -The `ugly` format uses simple variable substitution. A variable looks like -`!!(*= $this *)!!`. The variables are: - -* `vhost`: part of the path to the directory where the software is - served from. In the mySociety files, it usually comes as - `/data/vhost/!!(*= $vhost *)!!` -- you should replace that whole - port with a path to the directory where your Alaveteli software - installation lives, e.g. `/var/www/` -* `vhost_dir`: the entire path to the directory where the software is - served from. -- you should replace this with a path to the - directory where your Alaveteli software installation lives, - e.g. `/var/www/` -* `vcspath`: the name of the alaveteli checkout, e.g. `alaveteli`. - Thus, `/data/vhost/!!(*= $vhost *)!!/!!(*= $vcspath *)!!` might be - replaced with `/var/www/alaveteli` in your cron tab +#### Thin + +**Template Variables:** + +* `vhost_dir`: the full path to the directory where alaveteli is checked out. + e.g. If your checkout is at `/var/www/alaveteli` then set this to `/var/www` +* `vcspath`: the name of the directory that contains the alaveteli code. + e.g. `alaveteli` +* `site`: a string to identify your alaveteli instance * `user`: the user that the software runs as + +There is a rake task that will help to rewrite this file into one that is +useful to you. Change the variables to suit your installation. + + pushd /var/www/alaveteli + bundle exec rake config_files:convert_init_script \ + DEPLOY_USER=alaveteli \ + VHOST_DIR=/var/www \ + VCSPATH=alaveteli \ + SITE=alaveteli \ + SCRIPT_FILE=/var/www/alaveteli/config/sysvinit-thin.ugly > /etc/init.d/alaveteli + popd + + chown root:alaveteli /etc/init.d/alaveteli + chmod 754 /etc/init.d/alaveteli + +Start the application: + + service alaveteli start + +### Generate alert daemon + +One of the cron jobs refers to a script at `/etc/init.d/alaveteli-alert-tracks`. This +is an init script, which can be generated from the +`config/alert-tracks-debian.ugly` template. This script sends out emails to users subscribed to updates from the site – known as [`tracks`]({{ site.baseurl }}docs/installing/email/#tracks-mail) – when there is something new matching their interests. + +**Template Variables:** + +* `daemon_name`: The name of the daemon. This is set by the rake task. +* `vhost_dir`: the full path to the directory where alaveteli is checked out. + e.g. If your checkout is at `/var/www/alaveteli` then set this to `/var/www` +* `vcspath`: the name of the directory that contains the alaveteli code. + e.g. `alaveteli` * `site`: a string to identify your alaveteli instance +* `user`: the user that the software runs as There is a rake task that will help to rewrite this file into one that is -useful to you, which can be invoked with: +useful to you. Change the variables to suit your installation. - bundle exec rake config_files:convert_crontab \ - DEPLOY_USER=deploy \ - VHOST_DIR=/dir/above/alaveteli \ - VCSPATH=alaveteli \ - SITE=alaveteli \ - CRONTAB=config/crontab-example > crontab - -You should change the `DEPLOY_USER`, `VHOST_DIR`, `VCSPATH` and `SITE` -environment variables to match your server and installation. You should also -edit the resulting `crontab` file to customize the `MAILTO` variable. - -One of the cron jobs refers to a script at `/etc/init.d/foi-alert-tracks`. This -is an init script, a copy of which lives in `config/alert-tracks-debian.ugly`. -As with the cron jobs above, replace the variables (and/or bits near the -variables) with paths to your software. You can use the rake task `rake -config_files:convert_init_script` to do this. + pushd /var/www/alaveteli + bundle exec rake RAILS_ENV=production config_files:convert_init_script \ + DEPLOY_USER=alaveteli \ + VHOST_DIR=/var/www \ + VCSPATH=alaveteli \ + SITE=alaveteli \ + SCRIPT_FILE=/var/www/alaveteli/config/alert-tracks-debian.ugly > /etc/init.d/alaveteli-alert-tracks + popd + + chown root:alaveteli /etc/init.d/alaveteli-alert-tracks + chmod 754 /etc/init.d/alaveteli-alert-tracks + +Start the alert tracks daemon: + + service alaveteli-alert-tracks start + +### Generate varnish purge daemon `config/purge-varnish-debian.ugly` is a similar init script, which is optional -and not required if you choose not to run your site behind Varnish (see below). -Either tweak the file permissions to make the scripts executable by your deploy -user, or add the following line to your sudoers file to allow these to be run -by your deploy user (named `deploy` in this case): +and not required if you choose not to run your site behind Varnish (see below). It notifies Varnish of cached pages that need to be purged from Varnish's cache. It will not run if Varnish is not installed. - deploy ALL = NOPASSWD: /etc/init.d/foi-alert-tracks, /etc/init.d/foi-purge-varnish +**Template Variables:** -The cron jobs refer to a program `run-with-lockfile`. See [this -issue](https://github.com/mysociety/alaveteli/issues/112) for a discussion of -where to find this program, and how you might replace it. This [one line -script](https://gist.github.com/3741194) can install this program system-wide. +* `daemon_name`: The name of the daemon. This is set by the rake task. +* `vhost_dir`: the full path to the directory where alaveteli is checked out. + e.g. If your checkout is at `/var/www/alaveteli` then set this to `/var/www` +* `vcspath`: the name of the directory that contains the alaveteli code. + e.g. `alaveteli` +* `site`: a string to identify your alaveteli instance +* `user`: the user that the software runs as -## Set up production web server +There is a rake task that will help to rewrite this file into one that is +useful to you. Change the variables to suit your installation. -It is not recommended to run the website using the default Rails web server. -There are various recommendations here: http://rubyonrails.org/deploy + pushd /var/www/alaveteli + bundle exec rake RAILS_ENV=production config_files:convert_init_script \ + DEPLOY_USER=alaveteli \ + VHOST_DIR=/var/www \ + VCSPATH=alaveteli \ + SITE=alaveteli \ + SCRIPT_FILE=/var/www/alaveteli/config/purge-varnish-debian.ugly > /etc/init.d/alaveteli-purge-varnish + popd -We usually use Passenger / mod_rails. The file at `conf/httpd.conf-example` -gives you an example config file for WhatDoTheyKnow. At a minimum, you should -include the following in an Apache configuration file: + chown root:alaveteli /etc/init.d/alaveteli-purge-varnish + chmod 754 /etc/init.d/alaveteli-purge-varnish - PassengerResolveSymlinksInDocumentRoot on - PassengerMaxPoolSize 6 # Recommend setting this to 3 or less on servers with 512MB RAM +Start the alert tracks daemon: -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`. + service alaveteli-purge-varnish start + + +## 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](https://groups.google.com/forum/#!forum/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 + + cp /var/www/alaveteli/config/httpd.conf-example \ + /etc/apache2/sites-available/alaveteli + +Disable the default site and enable the `alaveteli` VirtualHost + + a2dissite default + a2ensite alaveteli + +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 + + cp /var/www/alaveteli/config/httpd-ssl.conf.example \ + /etc/apache2/sites-available/alaveteli_https + a2ensite alaveteli_https -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 and 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. A minimal configuration would look something like -this: +Force HTTPS requests from the HTTP VirtualHost - <VirtualHost *:443> - ServerName www.yourdomain + cp /var/www/alaveteli/config/httpd-force-ssl.conf.example \ + /etc/apache2/vhost.d/alaveteli/force-ssl.conf - ProxyRequests Off - ProxyPreserveHost On - ProxyPass / http://localhost:80/ - ProxyPassReverse / http://localhost:80/ - RequestHeader set X-Forwarded-Proto 'https' +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. - SSLEngine on - SSLProtocol all -SSLv2 - SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM + openssl genrsa -out /etc/ssl/private/www.example.com.key 2048 + chmod 640 /etc/ssl/private/www.example.com.key - SSLCertificateFile /etc/apache2/ssl/ssl.crt - SSLCertificateKeyFile /etc/apache2/ssl/ssl.key - SSLCertificateChainFile /etc/apache2/ssl/sub.class2.server.ca.pem - SSLCACertificateFile /etc/apache2/ssl/ca.pem - SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown + 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 - </VirtualHost> +Check the configuration and fix any issues -Notice the line `RequestHeader` that sets the `X-Forwarded-Proto` header. This -is important. This ultimately tells Rails that it's serving a page over https -and so it knows to include that in any absolute urls it serves. + 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 + +<div class="attention-box"> + <strong>Note:</strong> For historical reasons, <code>nginx-ssl.conf.example</code> has the path to Alaveteli set as <code>/var/www/alaveteli/alaveteli</code> – you will need to manually change this to <code>/var/www/alaveteli</code>, or to the root of your Alaveteli install +</div> + +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 + + 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 + +<div class="attention-box"> + <strong>Note:</strong> For historical reasons, <code>nginx.conf.example</code> has the path to Alaveteli set as <code>/var/www/alaveteli/alaveteli</code> – you will need to manually change this to <code>/var/www/alaveteli</code>, or to the root of your Alaveteli install +</div> + +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 + +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]({{ site.baseurl}}docs/running/server/). +## What next? + +Check out the [next steps]({{ site.baseurl }}docs/installing/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]({{ site.baseurl }}docs/installing/next_steps/), depending on how serious they are, but + ideally you should try to find out what's gone wrong. + + +<div class="attention-box"> + <strong>Note:</strong> If you have setup your install of Alaveteli for production, you will need to temporarily remove the file <code>config/rails_env.rb</code>, which is used to force the rails environment to production, and edit your <code>.bundle/config</code> file to remove the <code>BUNDLE_WITHOUT</code> line that excludes development dependencies. After you have done this, as the alaveteli user, run <code>bundle install</code>. You will also need to make alaveteli the owner of <code>/var/www/alaveteli/log/development.log</code>, and run the database migrations. + + <pre><code>chown alaveteli:alaveteli /var/www/alaveteli/log/development.log +sudo -u alaveteli bundle exec rake db:migrate</code></pre> + +You should then be able to run the tests. Don't forget to restore <code>config/rails_env.rb</code> when you're done. You will probably see some errors from cron jobs in the meantime, as they'll be running in development mode. + +</div> + + * **Incoming emails aren't appearing in my Alaveteli install** - First, you need to check that your MTA is delivering relevant - incoming emails to the `script/mailin` command. There are various - ways of setting your MTA up to do this; we have documented - [one way of doing it]({{ site.baseurl }}docs/installing/email/#troubleshooting-exim) - in Exim, including a command you can use to check that the email - routing is set up correctly. - - Second, you need to test that the mailin script itself is working - correctly, by running it from the command line, First, find a - valid "To" address for a request in your system. You can do this - through your site's admin interface, or from the command line, - like so: - - $ ./script/console - Loading development environment (Rails 2.3.14) - >> InfoRequest.find_by_url_title("why_do_you_have_such_a_fancy_dog").incoming_email - => "request-101-50929748@localhost" - - Now take the source of a valid email (there are some sample emails in - `spec/fixtures/files/`); edit the `To:` header to match this address; - and then pipe it through the mailin script. A non-zero exit code - means there was a problem. For example: - - $ cp spec/fixtures/files/incoming-request-plain.email /tmp/ - $ perl -pi -e 's/^To:.*/To: <request-101-50929748@localhost>/' /tmp/incoming-request-plain.email - $ ./script/mailin < /tmp/incoming-request-plain.email - $ echo $? - 75 - - The `mailin` script emails the details of any errors to - `CONTACT_EMAIL` (from your `general.yml` file). A common problem is - for the user that the MTA runs as not to have write access to - `files/raw_emails/`. + See the [general email troubleshooting guide]({{ site.baseurl }}docs/installing/email#general-email-troubleshooting). * **Various tests fail with "*Your PostgreSQL connection does not support unescape_bytea. Try upgrading to pg 0.9.0 or later.*"** |