Yet another step-by-step guide
There are a lot of tutorials/installation logs online about installing any of the mentioned software and combinations of them, but I sincerely couldn’t find a guide for this exact combination. Not a big deal, it is always possible to open a few tutorials and follow them in parallel. However, sometimes the tutorials disagree on certain points. Sometimes things simply refuse to work. And my bookmarks aren’t becoming any less messy as time goes by. So, I’m going to document a process which works for me, and hopefully it will work for somebody else.
Disclamer
This guide assumes you’ll be the only person using the machine, or that you can trust other persons 100%, even with your most sensitive data (probably not a good assumption). I will try to note where some of the steps might create the risk if this is not the case, but please DO your homework in such environments. Also, it might be a good idea to have/hire/consult an expert if you’re planning on having a shared and untrusted environment. This setup is intended with solo developers in mind, and for development environment only. Do NOT use this exact configuration for production.
Debian
I use Debian for a lot of servers, and am quite happy with it. In this guide I’m using 6.0.3-i386-netinst, but any 6.0.x should do. For development environment I use virtual machines + ssh, and would recommend you to do the same. Hint: taking snapshots before installing/upgrading (a group of) something(s) is the key to less frustration (and less blog posts like this one).
If you don’t have your preferred partitioning scheme, guided partitioning on whole disk with everything in one partition works good enough for development. For packages, I chose SSH server and standard system utilities.
Additional tools and configuration
Depending on Debian version and package selection, sudo is most likely not installed. Therefore:
1
2
3
4
5
| $ su -
Password:
# apt-get install sudo
# usermod -G sudo snarez
# exit |
$ su -
Password:
# apt-get install sudo
# usermod -G sudo snarez
# exit
You may need to relog after this.
Now, time to install the editor of choice for config files etc. You may be happy with default available editors (vi, nano..), but I use vim for everything including development. If you don’t have a favorite CLI editor, consider familiarizing yourself with one – vi is a good choice as it is present on almost any machine.
Also, now is a good time to install git, curl, and SSH if you haven’t selected it from packages.
1
| $ sudo apt-get install vim git curl ssh |
$ sudo apt-get install vim git curl ssh
RVM and ruby
As can be seen on official rvm website, the best way to install rvm is with curl. After install, you need to reload the .profile using source or by relogging:
1
2
| $ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
$ source ~/.profile |
$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
$ source ~/.profile
Now it's time to install your favorite ruby version, in my case it is ruby enterprise edition. It requires some dev headers and a "non-broken c++ compiler", so install them first.
1
2
| $ sudo apt-get install build-essential zlib1g-dev libssl-dev libreadline5-dev
$ rvm install ree |
$ sudo apt-get install build-essential zlib1g-dev libssl-dev libreadline5-dev
$ rvm install ree
One of the things that I really like about ree (and passenger) is that they do sanity checks before installing, and print nicely colored instructions in case something is missing. Kudos to phusion for making a really user-friendly CLI installer.
Passenger and nginx
To install passenger with our ree we'll use the gem installation, as mentioned in official install instructions. First, it is necessary to install curl dev headers with SSL support, openssl or gnutls. I personally use openssl.
Also, make sure you're using the desired ruby version to install passenger into.
1
2
3
4
| $ sudo apt-get install libcurl4-openssl-dev
$ rvm use ree
$ gem install passenger
$ rvmsudo passenger-install-nginx-module |
$ sudo apt-get install libcurl4-openssl-dev
$ rvm use ree
$ gem install passenger
$ rvmsudo passenger-install-nginx-module
Default installation and options (should) work just fine - I never had any problems.
An init script for nginx is really useful, you may find one here. There are many similar scripts available on the internet, but pay attention to PATH and DAEMON variables.
Download to /etc/init.d, allow execution and make sure it starts/stops with your machine:
1
2
3
| $ sudo wget https://gist.github.com/gists/2000616/download -P /etc/init.d
$ sudo chmod 755 /etc/init.d/nginx
$ sudo update-rc.d -f nginx defaults |
$ sudo wget https://gist.github.com/gists/2000616/download -P /etc/init.d
$ sudo chmod 755 /etc/init.d/nginx
$ sudo update-rc.d -f nginx defaults
PostgreSQL
Debian being debian, PostgreSQL 8.4 is still the latest available version to install out-of-the-box. In order to install the 9.1, you have to add backports by adding the following to /etc/apt/sources.list
deb http://backports.debian.org/debian-backports squeeze-backports main
Update apt and install postgreSQL from backports. Also, in order for pg gem to be able to connect to database, we need libpq-dev headers:
1
2
| $ sudo apt-get update
$ sudo apt-get -t squeeze-backports install postgresql-9.1 libpq-dev |
$ sudo apt-get update
$ sudo apt-get -t squeeze-backports install postgresql-9.1 libpq-dev
Now, configure the postgresql to allow local access, so rails can use it.
WARNING: potetntial security risk if untrusted persons/apps are using the same computer.
Edit the /etc/postgresql/9.1/main/pg_hba.conf, near the end of file (line 90)
local all all peer
and change peer to trust
local all all trust
and restart postgresql server
1
| $ sudo /etc/init.d/postgresql restart |
$ sudo /etc/init.d/postgresql restart
Project-specific rails
Create a directory structure. I use ~/rails/<rails_version>/<project_name>. Then create a gemset for use by desired ruby version, instruct rvm to use it in that directory, and to trust the .rvmrc:
1
2
3
4
5
6
7
8
9
| $ mkir -p rails/3.2/testapp
$ cd rails/3.2/testapp
$ rvm use ree
$ rvm gemset create testapp
$ echo "rvm use ree@testapp" >> .rvmrc
$ rvm rvmrc trust
$ rvm source .rvmrc
$ rvm current
ree-1.8.7-2011.12@testapp |
$ mkir -p rails/3.2/testapp
$ cd rails/3.2/testapp
$ rvm use ree
$ rvm gemset create testapp
$ echo "rvm use ree@testapp" >> .rvmrc
$ rvm rvmrc trust
$ rvm source .rvmrc
$ rvm current
ree-1.8.7-2011.12@testapp
Time to install rails (finally)
1
| $ gem install rails -v=3.2 |
$ gem install rails -v=3.2
I prefer using project-specific rails, but you may install it in global gemset if you're sure you'll be using the same version across all your apps. Project specific gemsets are almost a must have.
Creating and configuring the app
Create a new project in curent folder, using postgresql as database. We'll skip the bundler installation, as some modifications to Gemfile are required anyway.
1
| $ rails new . --database=postgresql --skip-bundle |
$ rails new . --database=postgresql --skip-bundle
It's time to create the database and user for our app. In order to do it, we need to run the psql command line as user postgres:
1
2
3
4
5
6
7
8
9
| $ sudo -u postgres psql
=# create database testapp_db;
CREATE DATABASE
=# create user testapp_user with encrypted password 'testapp_pass';
CREATE ROLE
=# grant all privileges on database testapp_db to testapp_user;
GRANT
=# \q
$ |
$ sudo -u postgres psql
=# create database testapp_db;
CREATE DATABASE
=# create user testapp_user with encrypted password 'testapp_pass';
CREATE ROLE
=# grant all privileges on database testapp_db to testapp_user;
GRANT
=# \q
$
For development environments, I always use <appname>_db for database name and <appname>_user, <appname>_pass for username and password. Do I need to tell you to not to use this scheme in production?
Next step is to configure our rails app to use the same credentials. Open the config/database.yml and change the development section:
development:
adapter: postgresql
encoding: unicode
database: testapp_db
pool: 5
username: testapp_user
password: testapp_pass
Configure nginx to know about the app by editing /opt/nginx/conf/nginx.conf and adding the following at the end, before the last }
server {
listen 8000;
passenger_enabled on;
passenger_spawn_method smart;
rails_env development;
root /home/snarez/rails/3.2/testapp/public;
}
And finally, start nginx to make the app available:
1
| $ sudo /etc/init.d/nginx start |
$ sudo /etc/init.d/nginx start
Of course, if it was already started, or when you change the configuration (e.g. you create another app), use reload instead of start.
In order to allow correct loading of gems with rvm, you will need a initializer script
1
| $ wget https://gist.github.com/gists/2000626/download -P config/ |
$ wget https://gist.github.com/gists/2000626/download -P config/
Add rake and therubyracer gems to your Gemfile (why is this not included by default is a mystery to me...):
gem 'rake', '0.9.2.2'
gem 'therubyracer'
Time to install all the gems
And finally, your app should be ready to use. Navigate to http://<server_ip>:<port> and click the "About your application’s environment" link and it should work.
Just to make sure, let's do a final test
1
2
| $ rails g scaffold test foo:integer bar:string baz:text
$ rake db:migrate |
$ rails g scaffold test foo:integer bar:string baz:text
$ rake db:migrate
Navigate to http://<server_ip>:<port>/tests
That should be it :)
For testing purposes, you will need to grant privileges to create databases to user. Again, this is NOT recommended in production environment:
1
2
3
4
5
6
| $ sudo su postgres
$ psql
=# alter user testapp_user createdb;
ALTER ROLE
=# \q
$ exit |
$ sudo su postgres
$ psql
=# alter user testapp_user createdb;
ALTER ROLE
=# \q
$ exit