A Guide to Deploying Rails Apps
December 04, 2011 / Jigar Patel
Note: This is not a definitive guide or a tutorial. I have simply collected all my notes related to deployment and compiled them into a blog post. Please check the documentation of the tools/apps mentioned here.
There are three major steps in the deployment process.
###A) Choosing the host / server
There are different types of hosting options that suit different people. You should choose an option depending on your requirements, budget and skills.
These are the popular hosting options in rails community
- Shared Hosts e.g Dreamhost
- VPS providers e.g Linode, Slicehost
- Cloud servers e.g EC2, Rackspace Cloud (More or less similar to VPS boxes)
- Dedicated Servers e.g Softlayer, Rackspace
- PaaS Providers e.g Heroku, EngineYard
Choose shared hosts for extremely small personal projects only. These are cheaper than the rest. However, these are extremely low on resources and the host may terminate your account if your scripts are consuming resources more than what your account is allotted. Additionally, you do not get root access to your server.
Dreamhost is a popular shared host for rails.
I tend to put VPS boxes and cloud servers in the same basket. Although their underlying technologies are different, as an end user ,I get more or less the same functionalities and same performance. Simply put these are virtual machines hosted on large hardware boxes and behave almost like a typical UNIX box. You can get memory configurations ranging from 64 MB to 68.4 GB (on EC2). The CPU power usually is directly proportional to your memory size. Only exception to this case is EC2 where you get to choose the CPU configuration as well.
These are the popular VPS and cloud server hosts -
|Prgmr||Cheap, Good for small projects and side projects. Difficult to manage as it comes with a management console.|
|Linode||Cheap, good for most projects. Nice service and consistent performance. High Memory / $|
|Rackspace Cloud||Per hour billing. Easy to setup. Costlier than Linode. Good performance.|
|Amazon EC2||Per hour billing. Expensive. Performance depends on configuration. CPU on micro instance sucks. Variety of configuration options. Choose Medium or Large CPU instance for CPU intensive apps.|
There are few other providers as well. The only negative point about VPS / cloud servers is poor disk I/O. Get a dedicated server if I/O causes to be a bottleneck.
Dedicated servers are expensive than the above mentioned options. They are full fledged hardware boxes. They usually come with a fully managed contract or self managed contract. Choose fully managed servers if you do not have in-house server admin skills. Some providers also let you choose an SSD (albeit at a premium). SSD’s provide a remarkable performance improvement in disk I/O.
Softlayer and Rackspace are popular options for dedicated boxes.
PaaS providers are the most expensive among the above mentioned hosts. They provide a fully managed ruby/rails stack built on top of services like Amazon EC2. Their performance is similar to the underlying cloud service. Choose them if you want to focus only on coding and forget about server admin stuff. Engine Yard and Heroku are the most popular options.
Engine Yard provides you a platform along with an EC2 instance. You can ssh into that instance and install anything.
Heroku is a bit more restrictive. You get a read only file system, you can only use postgres as your db and you do not get ssh access to the server. You can, however, install addons to overcome these restrictions.
A1) Choosing the server config
Determine the number of users and the max number of requests/s that you want to handle.
Determine the amount of memory consumed by your services and application server instances.
Number of application server instances required = (Max requests/s) / (Time taken by the longest request)
Minimum memory required = Memory consumed by the services + number of application server instances required * memory consumed by each application server instance
A2) Free servers
If you are running short on cash, or you simply want a server to learn stuff or demonstrate a prototype, buying a server does not make sense. There are few providers that let you test the water before you dive.
EC2 Micro - Free for first year. Around 600 MB of RAM / Low CPU
Heroku - One free dyno (presumably forever). Good for a small site. No background jobs.
Engine Yard - 500 hours free with a new account. One medium CPU EC2 instance. Extremely powerful.
B) Setting up the server
The hosts typically let you choose the operating system and mail you the root access details. In case of EC2, you have to download the .pem files.
The next steps are based for Ubuntu Server 10.04. Refer to the documentation of the OS in case you choose another OS. The steps, however, remain the same.
B1) Setup user accounts
Do not deploy using the root account or your personal account. It is recommended that you create a separate account for deploying apps.
1) ssh into the system using root credentials
2) Change the root password
3) Create new group for deployers
4) Give sudo privileges to users of deployers group
Issue the visudo command
Scroll down to the bottom and add the following two lines
Save and Exit.
5) Create new user/s
6) Add deployer user to deployers group
7) Logout and login as deployer
B2) Preparing the stack
You can now install the tools/software necessary for your application. Replace the commands for tools like Apache/MySQL with the commands for your tools.
1) Update the system
2) Install MySQL and libmysqlclient16-dev [dependency for mysql2 gem]
3) Install Apache
4) Install Git, Curl and build-essential [to compile ruby]
5) Install rvm
6) Add the following line to ~/.bashrc
7) Install the necessary packages
8) Install ruby 1.9.2
9) Make 1.9.2 the default interpreter
10) Install bundler
11) Install passenger
12) Install Apache2 module
passenger-install will notify about the missing dependencies. Install them.
13) Passenger install will complete with instructions about adding adding some lines to apache config file. Add them to apache config file.
14) Restart Apache
Now your server is ready to serve rails apps.
C) Deploying application
This part requires changes both to your application and to the server. I am also assuming that the app is to be deployed using capistrano.
1) Add capistrano gem to the application and capify the app
Add to the Gemfile
Run bundle install and then capify
This will create a deploy.rb in the config folder. You can modify this file according to your config. The vanilla version is sufficient for normal apps.
2) Setup the database on the server
Change DATABASE_NAME and DB_USERNAME according to your settings.
ssh into the sever
Login to the MySQL database using the root password (blank by default)
Create database for the rails application
Create user for database
4) Create folder for app
5) Change ownership of the folder
6) Update deploy.rb file
Update the server addresses, repository details and APPLICATION_NAME in your deploy.rb file.
7) Update ssh keys on repository
Add server’s ssh keys to your repository (Github)
8) Setup folder for deploy
9) Create database.yml
Create database.yml in shared folder with proper credentials.
10) Make a cold deploy
11) Deploy with migrations
Your app is now deployed. You now need to configure Apache (or Nginx) so that it can serve your rails app.
12) Create a virtual host
13) Add the following to the virtual host
Change the IP address, domain name and the application name.
14) Enable the new site
15) Restart Apache
Your application is now deployed and live. :-)
P.S Let me know if you find any errors. I will fix ‘em.
P.S If you get stuck with any of the steps or need some extra guidance hit me on twitter. (@jagira). I will try to help if time permits.
P.S I am not a professional server admin and the above mentioned steps may violate some best practices. Share such instances with me.