I have successfully deployed a heavy Rails application to Linode or Digital Ocean, using these technologies:
- rbenv for Ruby installation
- nginx + Passenger for the application server
- PostgreSQL for the database server
- Capistrano to automate deploys (configure this first on your dev machine with your server IP and settings, I will not cover it here)
These are the steps that work for me:
Setting up the virtual machine
Create a new virtual machine
Follow the setup instructions of your hosting, being Linode or Digital Ocean, to create the node and set it up.
Set up date
Update packages
- apt-get update
- apt-get upgrade
Security
Create user
- adduser deploy
- usermod -a -G sudo deploy
- logout
Set up SSH key-authentication
On local:
- ssh-keygen
- copy the public key:
- scp ~/.ssh/id_rsa.pub deploy@example.com:~
On the server:
- ssh deploy@example.com
- enable the alias to list files:
- vim ~/.bashrc
- uncomment all aliases
- mkdir .ssh
- mv id_rsa.pub .ssh/authorized_keys
- chown -R deploy:deploy .ssh
- chmod 700 .ssh
- chmod 600 .ssh/authorized_keys
- logout (test the new authentication)
Set up SSH
- sudo vim /etc/ssh/sshd_config
- Switch PermitRootLogin to no
- sudo service ssh restart
Set up firewall
Set up fail2ban
Set up if you have enough free memory, as it tends to eat it.
- sudo apt-get install -y fail2ban
Setup Ruby
Install Git
- sudo apt-get install -y git
Install rbenv
Install Ruby
- sudo apt-get install -y curl gnupg build-essential
- rbenv install -l (look for the latest version)
- rbenv install 2.3.3 (or the latest available version at this moment)
- rbenv global 2.3.3
- rbenv rehash
- vim .gemrc
- Paste this: gem: --no-document
Setup servers
Install nginx + Passenger
- Install following the documentation:
Install PostgreSQL
- Install following the documentation:
Setup libraries
Install node.js
Needed to pre-compile assets.
- sudo apt-get install -y nodejs
Install bundler
- get install bundler
- rbenv rehash
Setup the application
Create the user in PostgreSQL
- createuser username --pwprompt
- createdb -Ousername -Eutf8 db_name
- Test it:
- psql db_name --user username --password
Deploy the code
* On the server:
* sudo mkdir -p /srv/yoursite.com
* sudo chown deploy:deploy /srv/yoursite.com
* On your dev machine:
* bundle exec cap production deploy:check (it will throw an error because it doesn't find the database)
* On the server:
* cd /srv/yoursite.com/shared/config
* vim database.yml (paste your database config)
* vim secrets.yml (paste your secrets config)
* On your dev machine:
* bundle exec cap production deploy
* bundle exec cap production whenever:update_crontab
Configure logrotate