Abecto
25Oct/101

Setting up a new VPS on Linode

I host most of my personal and freelance sites on Virtual Private Servers. Why not shared hosting? Primarily because of the word "private". A VPS gives you full control of your own server, and the freedom to configure it as you wish, which in my experience is a must when hosting Ruby on Rails applications.

I recently had to change Virtual Private Server provider and made the switch to the excellent Linode. A colleague recommended them and I've been impressed with their service, cost, features and reliability.

While making the switch I took the opportunity to document the steps I took to setup a fresh VPS, primarily for hosting Ruby on Rails, but also as a Git server and Subversion server. Here are those steps, for my own future reference, but if others find it useful, all well and good...

Initial setup

Linode comes with a number of pre-configured "StackScripts" which automates setting up of various software on your server when it boots for the first time. As my server would be hosting Ruby on Rails applications, I chose the "Apache, MySQL, Ruby Setup" Stackscript, on Debian 5.

After the initial boot, Apache, Mysql and Ruby were indeed installed by the script. However, I noticed the Ruby Gems installation did not complete, so I did it manually as follows:

wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
tar xzvf rubygems-1.3.6.tgz
cd rubygems-1.3.6
ruby setup.rb

This installs the 'gem' binary to /usr/local/bin, so no need to update $PATH.

I won't go into detail about the various gems I installed, as apart from the obvious gems, these vary depending on your application(s) requirements. However, while installing gems, I did encounter problems with the mysql gem failing to compile as it required the libmysqlclient-dev package:

apt-get install libmysqlclient-dev
gem install mysql -- --with-mysql-dir=/usr/bin/mysql_config

Hello Joe!

Before I continued with anything else, I installed my first and favourite Linux text editor - Joe!

apt-get install joe

Joe is quite paranoid and automatically creates backups of all modified files. This litters the filesystem with lots of files with names ending in ~, which gets irritating, fast. I disable auto-backups like so:

edit /etc/joe/joerc
Find line containing 'Default local options'
add under it '-nobackups'
save

Git

Next up, version control, starting with Git.

apt-get install git-core

Running a private Git server using gitosis takes a little more work, so I'll point you in the direction of Garry Dolley's excellent tutorial.

I did note while following this tutorial that python-setuptools had to be installed:

apt-get install python-setuptools

Subversion

I have a number of older projects which I have not yet ported to Subversion, so better install that too right?

apt-get install subversion

I like being able to browse my SVN repository in my browser, so I updated Apache with mod-DAV.

apt-get install libapache2-svn
a2enmod dav

I don't want people snooping my source code, so next up was enabling SSL in Apache:

a2enmod ssl

I then created a new virtualhost for browsing the repository, with SSL and HTTP authentication:

<VirtualHost *:443>
  ServerName my.host.name

  SSLEngine on
  SSLCertificateFile /path/to/certificate/file
  SSLCertificateKeyFile /path/to/certificate/key/file
  SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

  <Location />
    DAV svn
    SVNPath /path/to/svn/repository/
    AuthType Basic
    AuthName "Restricted Access"
    AuthUserFile /path/to/password/file
    Require valid-user
  </Location>

  ErrorLog /path/to/error/log
  CustomLog /path/to/access/log combined
</VirtualHost>

Note, there are still further steps here to setup the SSL certificate (I used self-signed certs) and the HTTP authentication password file. But I'll not go into detail on that, a quick Google search will reveal plenty of guides to doing both.

Nginx

Nginx is a slim and snappy web server, great for serving up static files super fast and acting as a reverse proxy to Rails application servers (e.g. Mongrel/Thin/Unicorn). While I often just stick with Apache as a web server, I've been experimenting with Nginx and so installed from source as follows:

Note: For rewrite in Nginx, the PCRE library had to be installed (See http://www.cyberciti.biz/faq/debian-ubuntu-linux-install-libpcre3-dev/):

apt-get install libpcre3 libpcre3-dev

Download the latest stable source code from http://wiki.nginx.org/NginxInstall, extract, configure and compile.

tar xzfv nginx-0.8.53.tar.gz
cd nginx-0.8.53
./configure --with-http_ssl_module
make
make install

Usergroups

Simple system administration stuff, but I like to have a staff usergroup where I put all my users. This allows for assigning permissions more easily to this group, and in turn to those users (see the following section on SSH):

addgroup <usergroupname>
adduser <username> --ingroup <usergroupname>

Lock it down!

SSH is the doorway into my server, so I like to keep it locked pretty tight. The following are a few tweaks I make to the default SSH Daemon configuration /etc/ssh/sshd_config:

Change: LoginGraceTime 120
To: LoginGraceTime 40

Change: PermitRootLogin yes
To: PermitRootLogin no

Disable password authentication in favour of RSA authentication (read more on setting this up).

Change: PasswordAuthentication yes
To: PasswordAuthentication no

Under "Authentication:" add:

MaxAuthTries 3

If a staff group exists and it has existing users, add at the end of the file:

AllowGroups staff

Finally, after saving those changes, reload the SSH daemon so they take effect (double check all your changes first, as you might lock yourself out if you made a mistake):

/etc/init.d/ssh reload

Rainer Wichmann's write-up at http://www.la-samhna.de/library/brutessh.html is well worth reading for more SSH security tips.

Monitoring

Monitoring your critical services is a must for any production system, and as far as I'm concerned you need look no further than monit. I've played around with God and while writing your monitoring configuration with Ruby is nice, I found it unstable, buggy and the memory footprint far too large, as have others. Monit is proven, stable, lightweight and configuring it is a sintch.

apt-get install monit

ImageMagick & Friends

If you do any kind of image manipulation in your Rails apps you'll inevitably need ImageMagick and RMagick (or mini_magick, ImageScience etc).

Installing these can be a real pain (see OS X!), but thankfully I found it straightforward on Debian 5, with one gotcha, I had to use rmagick v2.12.2 as later versions refused to compile.

apt-get install imagemagick
apt-get install libmagick9-dev
gem install rmagick --no-ri --no-rdoc --version=2.12.2
gem install mini_magick --no-ri --no-rdoc

Once all installed, remove libmagick9-dev and its dependencies as they are no longer needed:

apt-get remove libmagick9-dev
apt-get autoremove

Other bits and bobs

The Wordpress Google Reader module I use on this site requires the PHP Curl module, installed as follows:

apt-get install php5-curl

Wordpress also needs mod-rewrite for pretty URLs:

a2enmod rewrite

I also tend not to use sudo, instead preferring to switch user to root after I SSH into the server, so I usually remove it:

apt-get remove sudo

And don't forget to update your server's hostname:

hostname desired-host-name

Keeping things tidy

Finally, a little bit of house cleaning to remove any cruft left behind by Aptitude. Who knows, you might need the extra disc space one day!

apt-get clean

And we're done!