I tried deployment for the first time. Everyone told that it was a difficult thing to do. So I was actually afraid. I read through a tutorial and tried to do it. But there were some problems in the tutorial which I had to fix after trying many things. So I will explain step by step, the things to do while deploying to aws or digital ocean using capistrano, puma & nginx.
I believe you have a running rails application since I am not going to explain it from the absolute begining. I use figaro gem here to manage passwords, secrets and so on but you are free to use secrets.yml if thats what you are comfortable with. But it will need other tweaks and I am not going to explain it here.
First we are gonna add few gems to our application.
Gemfile
Now bundle the gems by running bundle install
.
We are now gonna start setting up capistrano. Run the command
]$ cap install STAGES=production
This will create few files. We will edit them in the process. First edit the Capfile in the root of your application
Capfile
Next we edit deploy.rb file in the config directory.
config/deploy.rb
I hope that you have not added database.yml & application.yml in your git tracking.
Setting up the server
Now the basic setup is complete. We have to get the server up and running. If you are using AWS select and launch an EC2 instance (I chose Ubuntu 14.04). It will ask you for all kinds of info. You have to generate a key-value pair to connect to EC2 and download the file. You can get the public ip of EC2 instance by clicking on the instance and viewing its details at the bottom.
If you are using digital ocean fire up a droplet and you will get the details of the root user in your mail.
We are gonna ssh into the server now.
]$ ssh -i path_to_pem_file ubuntu@public_ip # if aws
]$ ssh root@ip # if digital ocean
First update the existing packages.
]$ sudo apt-get update
]$ sudo apt-get upgrade
Next create a user named deploy for deploying the app.
]$ sudo useradd -d /home/deploy -m deploy
]$ sudo passwd deploy
Now add deploy to sudoers. Run sudo visudo
and add the following line below root ALL=(ALL:ALL) ALL
deploy ALL=(ALL:ALL) ALL
Now go to user deploy and install git. Then create an ssh key.
]$ sudo apt-get install git
Get the public key from your local system (.ssh/id_rsa.pub
) and add it to the server’s authorized ssh keys present at .ssh/authorized_keys
.
Now we are gonna install nginx.
]$ sudo apt-get install nginx
Now we are going to edit nginx site-config file
]$ sudo vim /etc/nginx/sites-enabled/default
Delete all the existing content and enter the following
/etc/nginx/sites-available/default
The configuration of nginx is done. Now we go to the rest of the app.
I am using postgresql as the db. So I will use that here as well. We are going to install postgresql.
]$ sudo apt-get install postgresql postgresql-contrib libpq-dev
Now we create a user for the production database. Usually user_name is the app_name
]$ sudo -u postgres createuser -s user_name
Now we set the password of the user from postgres console.
]$ sudo -u postgres psql
postgres=# \password user_name
After setting the password we create a database for the user.
]$ sudo -u postgres createdb -O user_name app_name_production
Now we go on to install rvm & ruby.
]$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
]$ curl -sSL get.rvm.io | bash -s stable
]$ rvm requirements
]$ rvm install ruby_version # eg: rvm install 2.2.2
]$ rvm use ruby_version
Open your .bash_profile and copy last line to .bash_rc to enable rvm even in non-login shell.
We installed rvm and ruby. We also specified the ruby we are going to use. Now we will install bundler.
]$ gem install bundler
Now we will create the files necessary for capistrano for deployment.
]$ mkdir app_name
]$ mkdir -p app_name/shared/config
]$ vim app_name/shared/config/database.yml
We are only adding the production data to database.yml
/home/deploy/app_name/shared/config/database.yml
Then create application.yml and add the following
/home/deploy/app_name/shared/config/application.yml
You can generate a new secret by running rake secret
from your local. Now the server is done. We move to the local and edit production.rb.
/home/user/app_name/config/deploy/production.rb
Everything is done. To deploy with capistrano just run
]$ cap production deploy
All files will be created by capistrano. Migrations will be done and assets will be precompiles as well.
Now we move back to server and restart nginx.
]$ sudo service nginx restart
That is the entire setup necessary. Now when you restart nginx if it fails you can find the failure reason with
]$ sudo nginx -t
And then search google to find the solution. :D
Go to http://your_ip to view the site.