How to deploy a Rails app to a VPS (or dedicated s

2019-01-29 22:50发布

问题:

How can I deploy a Rails app to a VPS (virtual private server) or a dedicated server? It would be nice to have an easy to follow guide.

I know about scripts to automate the process, but I think it's better to have everything under control, in order to understand better the process.

回答1:

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

  • dpkg-reconfigure tzdata

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

  • sudo iptables -L (it should show a void table)
  • sudo vim /etc/iptables.firewall.rules
  • Paste this: https://gist.github.com/davidmles/89fc88e48e17cf8252bfca374e46355f#file-iptables-firewall-rules
  • sudo iptables-restore < /etc/iptables.firewall.rules
  • sudo iptables -L (now it should show the configured rules)
  • sudo vim /etc/network/if-pre-up.d/firewall
  • Paste this: https://gist.github.com/davidmles/89fc88e48e17cf8252bfca374e46355f#file-firewall
  • sudo chmod +x /etc/network/if-pre-up.d/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

  • git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
  • echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
  • echo 'eval "$(rbenv init -)"' >> ~/.bashrc
  • source ~/.bashrc
  • git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

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:
    • https://www.phusionpassenger.com/library/install/nginx/install/oss/jessie/

Install PostgreSQL

  • Install following the documentation:
    • https://wiki.postgresql.org/wiki/Apt#PostgreSQL_packages_for_Debian_and_Ubuntu

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

  • Follow this guide: * https://gorails.com/guides/rotating-rails-production-logs-with-logrotate


回答2:

I deployed my rails application to my production servers (it's a cluster) with Capistrano before, but I found that Capistrano is a bit complex and sometimes even became trouble maker... So I wrote my deployment script by bash shell script.

I have put it on github with a brief guide: deploy_rails