It seems like your cool rails application is ready to go wild, That’s great! sooner the better. Before you made up your mind for deploying rails application to a VPS – you should know that it’s not a very easy (and only) process. You could have deployed using some other way e.g Heroku, probably much faster.
Manually deploying your rails application to a VPS can be very frustrating for beginners but if you’re willing to learn all those stuffs (GNU/Linux, terminal commands, server administration stuffs and more) or may be you want full control over the things – then probably you made the best choice.
“step by step” guide for deploying a Rails application to VPS
1. get a VPS and install Ubuntu 12.04 LTS
If you don’t already own a VPS then buy one. I recommend Linode (I’ve been using it for my blog as well as for other rails applications, I absolutely love their service). They’ve plans starting at $20/month for 512MB 1024MB 2048 RAM. (which should be sufficient for testing and launch, you can upgrade easily so start with small one, unless you’re sure how much memory you need).
Checkout Linode VPS plans (starting @ $20/month)
Another Great Option – Digital Ocean (starting @$5/mo, 20 GB SSD, 1TB Data, 512 MB RAM, free backups and more!) You can use promo code DEPLOY2DO to get $10 credit (worth two months of free hosting), so you can give it a try without any risk.
I’ve written more about it recently – Digital Ocean Hosting Review.
After getting a VPS ready (usually within few minutes), choose an operating system – I recommend Ubuntu (unless you’ve some specific choice, due to some previous experience with a GNU/Linux distribution such as ArchLinux, Debian etc) – select latest LTS release, ie Ubuntu 12.04 LTS (precise pangolin).
Update! Now, Ubuntu 14.04 LTS is out and available. So, you should choose that. You may need to change few commands below. Although, if you go with 12.04, you can always upgrade.
2. Setting up the Server
When, the vps is ready (within few minutes, after you deploy and boot the server), SSH into the server and use your root account to login (you would get the root password from vps provider’s panel, while deploying the OS, in the above step #1).
ssh root@vps_ip_address
Now, first update the repository cache and the packages.
apt-get -y update apt-get -y upgrade
Creating a user
Using root account is not a good idea (of course for security reasons, that’s why there is something called sudo
, that would allow you to execute commands with root privilages). So lets create a user, e.g mrhuman, add him to sudo group (so that he can execute commands with root power).
adduser mrhuman --ingroup sudo
(it will ask you to enter some details, as well as the password for the user)
Using password authentication is not secure and it’s also not very efficient. Logout from the current session or switch to the newly created user with su user_name
command. In next step, we will be setting up the ssh-authentication.
setup ssh authentication
If you’ve not already generated public/private keys (most likely you already have a pair of public/private keys, e.g you might have generated it for github or bitbucket), then generate one and upload your public key to the vps server.
Type the command(on your local computer)
ssh-keygen scp ~/.ssh/id_rsa.pub mrhuman@vps_ip_address:
Login to the remote server with newly created user(mrhuman, in this case) and type
mkdir .ssh mv id_rsa.pub .ssh/authorized_keys
3. Install nginx server
In this guide I assume you’re using nginx server, Apache is another great option. Before installing nginx, first install the utility – python-software-properties, for installing packages via PPA, sometimes the packages available in repository are very outdated.
sudo apt-get -y install python-software-properties
Then install nginx from the PPA.
apt-add-repository -y ppa:nginx/stable apt-get -y update apt-get -y install nginx
After installing nginx you can type
sudo service nginx start
to start the nginx and visit the IP address your server, you should see the default page there.
4. Install ruby and other dependencies/gems
For managing ruby versions you should choose RVM or rbenv. In this guide I’m going with rbenv.
Before installing rbenv, lets install some common dependencies such as curl, git version control system, javascript runtime such as nodejs etc.
Installing nodejs
sudo apt-add-repository -y ppa:chris-lea/node.js sudo apt-get -y update sudo apt-get -y install nodejs
Installing curl and git
sudo apt-get -y install curl git-core
Now, install rbenv using an installer
curl https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash
Add rbenv to your path variable
After installing rbenv, Just add the following lines to the top of your ~/.bashrc
file.
export RBENV_ROOT=\"\${HOME}/.rbenv\" if [ -d \"\${RBENV_ROOT}\" ]; then export PATH=\"\${RBENV_ROOT}/bin:\${PATH}\" eval \"\$(rbenv init -)\" fi
Now, reload the shell by tying the command –
source ~/.bashrc
Install dependencies with rbenv-installer script
rbenv bootstrap-ubuntu-12-04
Installing Ruby
rbenv install 1.9.3-p327 rbenv rehash rbenv global 1.9.3-p327
Installing Bundler & Rake
gem install bundler --no-ri --no-rdoc gem install rake --no-ri --no-rdoc rbenv rehash
Install MySQL and Create database/user
I assume you’re using MySQL in production (or whatver like Postgresql, MongoDB etc, you need to install the required packages/dependenices and create database/user).
Installing MySQL
sudo apt-get -y install mysql-server libmysql++-dev
Now, create database and users (enter the root password, as entred in above step)
mysql -u root -p create database YOUR_DB_NAME; grant all on YOUR_DB_NAME.* to DB_USER@localhost identified by 'your_password_here'; exit
5. Setting up Capistrano for Deployment
Now, it’s time to set up capistrano for automating the deployment process. You would also need to have the source code hosted on a private repository (unless you want the source code to be available public) such as on github or bitbucket and add the remote repository to list of identified hosts (to avoid some error during deployment). Simply, ssh into the remote host (remote repository) e.g ssh github.com
or ssh bitbucket.org
(if you’re using bitbucket) from the remote server.
add following gems into your Gemfile.
gem 'mysql2' gem 'unicorn' gem 'capistrano'
and install those gems, by running bundle install
.
Now, type the command(of course, in root of your application directory)
capify .
It will create few files that you need to change. First update your Capfile (for the assets section), it should look like this:
Then, update database.yml file (!warning, you shouldn’t put this kind of file in git repository).
Next, add unicorn.rb and unicorn_init.sh (make it executable by running chmod +x unicorn_init.sh
) file to config directory.
Next unicorn_init.sh,
Then update config/deploy.rb file.
Don’t forget to change the variable names in above files (e.g replace YOUR_APP_NAME by your application name, git repository URL by your_repository address and more!)
6. Deploy!
That’s all, now it’s time to deploy!
I assume you’re already using git, so commit the latest changes and push it to master branch.
git add . git commit -am "add deployment configs" git push master
First setup the deployment configurations using the command –
cap deploy:setup
Then deploy it,
cap deploy
If things look OK (in fact, it may take a while and you may get some errors, just read the messages and act accordingly, rather than freaking out) then open the browser and visit the IP address (or domain, now you can set up DNS for the VPS)
Run the database migrations and start.
cap deploy:migrate cap deploy:start
Now, Your Rails app should be running fine, any problem? Drop a comment here, we’ll look into that.
Reference(s) and Recommended Link(s)
unicorn_init.sh where should this exist?
config directory, of course.
Oops i see where it is supposed to be. Failed to read. What happens if all i see if the nginx welcome page after capistrano has finished?
probably, you need to remove the default site configs : sudo rm /etc/nginx/sites-enabled/default and restart the server, I had already added it in the above recipes but there was some typo (in deploy.rb). I’ve fixed it.
In ubuntu whether 32 bit is good or 64bit is good for the $4.25/month config
hi,
Is this lines are necessary to add in deploy.rb file..
in task :setup_config”
run “mkdir -p #{shared_path}/config”
put File.read(“config/database.example.yml”), “#{shared_path}/config/database.yml”
puts “Now edit the config files in #{shared_path}.”
and this lines too
after “deploy:setup”, “deploy:setup_config”
task :symlink_config, roles: :app do
run “ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml”
end
is all above related to database.yml file and you menetioned to delete the database.yml file in git repositoy..
thanks,
somu
Hi
Thank you for your post.
And I have little problem.
I just add following lines to buttom of `Gemfile` file.
———————–
gem ‘mysql2’
gem ‘unicorn’
gem ‘capistrano’
———————–
And typing this command.
—————–
$ bundle install
—————–
And typing this command too.
———-
$ capify .
———-
By the way, I get some error.
——————————————————————————————–
The program ‘capify’ is currently not installed. You can install it by typing:
sudo apt-get install capistrano
——————————————————————————————–
So I just check bundle..
—————————————
$ bundle show|grep capistrano
* capistrano (2.15.4)
—————————————
Why I can’t use command that is `capify .`?
What should I do?
may be you are using RVM and it’s not loaded properly into your shell. Try running :
source ~/.rvm/scripts/rvm
I’m getting “sqlite3.h is missing” error.. on `cap deploy` … what should I do ?
You may need to install sqlite dev libraries, try running (on remote server, of course) this :
sudo apt-get install libsqlite3-dev