Skip to content
This repository has been archived by the owner on Mar 22, 2018. It is now read-only.

Setup a Server

Mark Orr edited this page Jul 14, 2014 · 22 revisions

By 2013 the version of Linux (Centos 5, 32 bit) on ratalacha (the original host for ratings.icu.ie) was beginning to show its age and so a new server (given the hostname aontas) with the (at that time) latest available Centos from Linode (version 6, 64 bit) was created. The initial plan was to host the new www.icu.ie (at that time, still in development) on the new server. It was also envisaged migrating ratings.icu.ie from ratalacha to aontas at some stage (which eventually happened in July 2014).

This page details how the new server was set up, including all the software required to run the ICU web apps. You might like to compare with the notes on how ratalacha was setup a couple of years before.

It's a good idea to keep, as far as possible, software versions the same in development and production environments. Below, comparisons are made between versions on aontas (the new Centos 6 production server), ratalacha (the old Centos 5 production server), abidjan (Mark's 2009 iMac) and mogadishu (Mark's 2013 MacBook Pro).

Create the new server

Currently we are using Linode as our VPS provider, so start by logging in. Then, from the Linodes tab, click Add a Linode, choose the latest Centos, a suitable data centre (London), a payment plan and a root password.

Set hostname and timezone

Following the Getting Started Guide: boot the server, note the IP address and ssh as root. Then:

$ echo "HOSTNAME=aontas" >> /etc/sysconfig/network
$ hostname aontas
$ ln -sf /usr/share/zoneinfo/UTC /etc/localtime
$ date # => Sun Nov 17 21:57:21 UTC 2013

Setup a DNS entry for aontas.icu.ie with our domain name service provider (currently Register365) and the server IP address to /etc/hosts:

176.58.112.239 aontas.icu.ie aontas

System update

Upgrade the existing packages (upgrades Centos to the very latest release in the 6.x series):

$ yum update
$ cat /etc/redhat-release # => CentOS release 6.4 (Final)

Install general stuff we'll definitely need:

$ yum install gcc gcc-c++ make ntp
$ gcc -v # => 4.4.7 (good news - the 4.1.2 version on _ratalacha_ had become a problem) 
$ yum install readline-devel openssl-devel

Install general stuff that is useful or we may need:

$ yum install tree # useful
$ yum install libxml2-devel libxslt-devel # might come in handy
$ yum install ImageMagick-devel # needed for the PaperClip gem

There are more yum-installs to do later, related to individual packages (see below).

Start the ntpd daemon

This service synchronises the system clock:

$ chkconfig ntpd on
$ service ntpd start

Setup a new user

This will be the user we normally login as and also under which the ICU web apps will run (below, replace uname with the chosen user name).

$ useradd -c "Mark Orr" -m uname
$ passwd uname
$ cd /home/uname
$ mkdir .ssh
$ touch .ssh/authorized_keys
$ chown -R uname:uname /home/uname/.ssh
$ chmod 700 /home/uname/.ssh
$ cd .ssh
$ chmod 500 authorized_keys
$ vi .ssh/authorized_keys  # setup keys
$ visudo # give uname some special powers

Secure the system

Following Securing Your Server:

  • disable root login via ssh
  • configure an ip4 firewall using iptables
  • for aontas, the directives were recorded in a handy script: /etc/my_firewall
  • configure an ip6 firewall using ip6tables, assuming ip6 is enabled (it was for anontas)
  • again, a script was made for aontas: /etc/my_ip6_firewall
  • at this stage in internet history, it's OK for a restrictive ip6 policy (i.e. drop most incoming)
  • install and configure Fail2Ban
  • note: the fail2ban logfile is in /var/log/fail2ban.log

Install and configure Apache

Following Apache2 Centos 6:

$ yum install httpd
$ service httpd start
$ chkconfig httpd on
$ chkconfig --list # check it's there

Configure /etc/httpd/conf/httpd.conf:

ServerAdmin [email protected]
ServerName 176.58.112.239

# Settings recommended for a 1GB Linode
<IfModule prefork.c>
StartServers       2
MinSpareServers    6
MaxSpareServers   12
MaxClients        80
MaxRequestsPerChild  3000
</IfModule>

# For the favicon
AddType image/x-icon .ico

Prepare a home for applications (and setup a simple test app to get us started):

$ mkdir /var/apps
$ chown uname:umane /var/apps
$ su uname
$ cd /var/apps
$ mkdir mark
$ cd mark
$ scp ratalacha.icu.ie:/var/apps/mark/* .

Prepare custom log directories in advance for the 3 expected apps:

$ cd /etc/httpd/logs # this is linked to /var/log/httpd
$ mkdir www ratings mark

Configure /etc/httpd/conf.d/vhost.conf (for now, just enough to get the test app working)

<VirtualHost 176.58.112.239:80>
    ServerName www2.markorr.net
    DocumentRoot /var/apps/mark
    CustomLog logs/mark/access.log combined
    ErrorLog logs/mark/error.log

    <Directory /var/apps/mark>
        AllowOverride None
        Order Allow,Deny
        Allow from all
    </Directory>
</VirtualHost>

Install Passenger

There are other options, but currently we use Passenger to serve Rails apps.

$ su -
$ yum install curl-devel httpd-devel apr-devel apr-util-devel
$ gem install passenger
$ passenger-install-apache2-module # compiles passenger and prints further instructions
$ vim /etc/httpd/conf/httpd.conf # follow instructions given by last command
$ /usr/sbin/apachectl graceful

Setup Apache and Rails log rotation

We're going to eventually have 2 Rails apps in /var/apps/www and /var/apps/ratings and separate Apache log files for each app in /var/log/httpd/www and /var/log/httpd/ratings so add a logrotate configuration file for each in app /etc/logrotate.d/. Following is the one for www (the one for ratings is similar).

/etc/logrotate.d/www

/var/apps/www/shared/log/*log {
    compress
    daily
    dateext
    delaycompress
    missingok
    notifempty
    olddir old
    rotate 30
    sharedscripts
    postrotate
        touch /var/apps/www/current/tmp/restart.txt
    endscript
}
/var/log/httpd/www/*log {
    missingok
    notifempty
    sharedscripts
    postrotate
        /sbin/service httpd reload > /dev/null 2>/dev/null || true
    endscript
}

And in case you're worried about the Rails log directories not yet existing, we can set them up now.

$ mkdir -p /var/apps/{www,ratings}/shared/log

Install and configure MySQL

Following this slightly older guide:

$ yum install mysql-server mysql-devel
$ chkconfig --levels 235 mysqld on
$ /etc/init.d/mysqld start
$ mysql_secure_installation  # answer yes to all recommended security options and choose a root password

The installed version was 5.1.69 to begin with, which compares with 5.0.95 for ratalacha, 5.1.66 for abidjan and 5.6.13 for mogadishu. By July 2014 (a year after the original install), after various yum updates, the aontas version had crept up to 5.1.73.

As for ratalacha, added this to /etc/my.cnf:

# So that new tables are created with the right encoding.
default-character-set=utf8
character-set-server=utf8
default-collation=utf8_unicode_ci

And restarted the service t make the changes take effect:

$ service mysqld restart

Create and setup users for the production databases:

mysql> CREATE DATABASE www_production;
mysql> GRANT ALL ON www_production.* to '...'@localhost identified by '...';
mysql> GRANT SELECT ON www_production.* to '...'@'%' identified by '...';

mysql> CREATE DATABASE ratings_production;
mysql> GRANT ALL ON ratings_production.* to '...'@localhost identified by '...';
mysql> GRANT SELECT ON ratings_production.* to '...'@'%' identified by '...';

The ratings database currently needs an extra setting for LOAD DATA INFILE:

use mysql;
update user set File_priv = 'Y' where User = 'ratings';
flush privileges;

Following this guide, setup the MySQL user for Linode-Longview (a monitoring service Linode provide):

mysql> CREATE USER 'linode-longview'@'localhost' IDENTIFIED BY '...';
mysql> flush privileges;

After installing Longview, you'll need to add these credentials to /etc/linode/longview.d/MySQL.conf.

Install Git

The system git is a little out of date but will probably do.

$ yum install git
$ git --version # => 1.7.1

This compares with 1.7.6 (ratalacha), 1.8.1 (abidjan) and 1.8.3 (mogadishu).

Install Ruby

The system ruby is surprisingly old and won't do at all:

$ yum install ruby
$ which ruby # => /usr/bin/ruby
$ ruby -v # => ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]

So compile and install the same version you're working with in development into /usr/local:

$ cd ~/src
$ wget http://cache.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p247.tar.gz
$ tar -zxvf ruby-2.0.0-p247.tar.gz
$ cd ruby-2.0.0-p247
$ ./configure --prefix=/usr/local
$ make
$ sudo make install
$ ruby -v # ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]
$ gem -v # 2.0.3 (1.8.23 on ratalacha, 1.8.23 on abidjan, 2.1.10 on mogadishu)
$ sudo /usr/local/bin/gem update --system
$ gem -v # => 2.1.11

Install or upgrade some basic gems:

$ sudo /usr/local/bin/gem install rake # 10.1.0 (same on ratalacha, abidjan and mogadishu)
$ sudo /usr/local/bin/gem install bundler # 1.3.5 (same ratalacha, abidjan and mogadishu)

Test installing any gems the apps need which, in the past, have been problematic:

$ sudo /usr/local/bin/gem install libv8 # 3.16.14.3 (same on abidjan and mogadishu, 3.11.8.17 on ratalacha)

Install Perl

The pre-installed system Perl is a little out of date.

$ which perl # => /usr/bin/perl
$ perl -v # => 5.10.1

Perl is used by the ICU apps, though not as much as Ruby, so install the latest version.

$ cd ~/src
$ wget http://www.cpan.org/src/5.0/perl-5.18.1.tar.gz
$ tar -zxvf perl-5.18.1.tar.gz
$ cd perl-5.18.1
$ ./Configure -des -Dprefix=/usr/local
$ make
$ make test
$ sudo make install
$ which perl # => /usr/local/bin
$ perl -v # => 5.18.1 (5.14.1 on _ratalacha_, 5.14.1 on _abidjan_, 5.16.1 on _mogadishu_)

Install ack (if, like Mark, you prefer it to grep):

$ sudo /usr/local/bin/cpan install App::Ack

In icu_ratings_app, Perl is used to generate export files (see bin/export.pl). Ruby doesn't have a Gem for writing DBF files (needed for SwissPerfect) but Perl has the CPAN module CAM::DBF. Other CPAN modules to install in support of this are DBI, DBD::mysql, YAML and Archive::Zip.

Install Redis

Currently Redis is used to store Irish translations and may find more use in the future. Compile and install (in /usr/local/bin) as a normal user:

$ cd ~/src
$ wget http://download.redis.io/releases/redis-2.6.16.tar.gz
$ tar -zxvf redis-2.6.16.tar.gz
$ cd redis-2.6.16
$ make # note - no mucking about with compiler flags as on ratalacha 32 bit system
$ make test # needed tcl, all passed
$ sudo make install
$ sudo chown root:root /usr/local/bin/redis*

Customise as root:

$ mkdir /etc/redis /var/lib/redis
$ cp src/redis-2.6.16/redis.conf /etc/redis
$ vim /etc/redis/redis.conf

Differences to defaults are (this is the same setup as ratalacha):

daemonize yes
bind 127.0.0.1
timeout 60
logfile /var/log/redis.log
# save 900 1
# save 300 10
# save 60 10000
dir /var/lib/redis
appendonly yes

Daemonize. Copy this gist to /etc/init.d/redis-server, correct the server path (it's in /usr/local/bin not /usr/local/sbin) and then:

$ chmod 755 /etc/init.d/redis-server
$ chkconfig --add redis-server
$ chkconfig --level 235 redis-server on
$ service redis-server start

Quick manual test:

$ redis-cli
$ redis> SET y 2013
$ redis> GET y # => "2013"
$ redis> exit

Skip Python

On ratalacha, it had been necessary to install a more up to date version (2.7.2) than the system version to help compile the libv8 gem, part of therubyracer, which the ICU apps use as a JavaScript runtime. However, on aontas, libv8 helpfully installed itself from a binary file, so no compilation was required.

The pre-installed /usr/bin/python is version 2.6.6. We'll assume we don't need a more modern one. Fail2ban (see the section on security), for example, uses python but only needs >= 2.3.