/ Deployment / Rails Deployment to DigitalOcean (Ubuntu 18.04)

1 — Create Droplet on DigitalOcean


2 — Getting your Droplet ready

Ssh to your new droplet & change default password, then:

Add new user (deploy)

  $ sudo adduser deploy (add user)
  $ adduser deploy sudo (give user the sudo permission)
  $ su deploy (switching instantly to the deploy user) OR exit 

3 — Set your ssh machine ssh key to your Droplet

=> This is to link your local machine with your server => So that don’t have to type password anymore to login to your Droplet

Generate ssh key (if you don’t have one yet)


Install ssh-copy-id

  $ brew install ssh-copy-id

Set your ssh key to your droplet

   $ ssh-copy-id root@YOUR-DROPLET-SERVER-IP (for root user)
   $ ssh-copy-id deploy@YOUR-DROPLET-SERVER-IP (for deploy user)

Try to ssh to your server

See if you no longer need password to login. If you can login without password, then its working!

4 — Setup connection of your Droplet with your GitHub repo via SSH

=> This is to link your GitHub repo with your server

  $ ssh -T git@github.com
  $ ssh-keygen -t rsa 
  $ cat ~/.ssh/id_rsa.pub
  $ copy that key and paste to your GitHub repo Deploy Key setting

5 — Install some dependencies for Ruby and Rails

  $ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
  $ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
  $ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

  $ sudo apt-get update
  $ sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev nodejs yarn 

6 — Install Ruby using rbenv

 git clone https://github.com/rbenv/rbenv.git ~/.rbenv
 echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
 echo 'eval "$(rbenv init -)"' >> ~/.bashrc
 exec $SHELL

git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL
$ rbenv install 2.5.1
$ rbenv global 2.5.1
$ ruby -v

7 — Install Bundler

$ gem install bundler
$ rbenv rehash

8 — Install Nginx

$ sudo apt-get install -y dirmngr gnupg
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
$ sudo apt-get install -y apt-transport-https ca-certificates
$ sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
$ sudo apt-get update
$ sudo apt-get install -y nginx-extras libnginx-mod-http-passenger
$ if [ ! -f /etc/nginx/modules-enabled/50-mod-http-passenger.conf ]; then sudo ln -s /usr/share/nginx/modules-available/mod-http-passenger.load /etc/nginx/modules-enabled/50-mod-http-passenger.conf ; fi
$ sudo ls /etc/nginx/conf.d/mod-http-passenger.conf

9 — Adding The Nginx Host

sudo vim /etc/nginx/sites-enabled/default

Paste the following:

server {
        listen 80;
        listen [::]:80 ipv6only=on;

        server_name MYDOMAIN.com;
        passenger_enabled on;
        rails_env    production;
        root         /home/deploy/MY_APP_NAME/current/public;

        # ActionCabel config (disable this if u r not using it)
        location /cable {
           passenger_app_group_name actioncable_websocket;
           passenger_force_max_concurrent_requests_per_process 0;    

        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;

**10 — Restart nginx **

$ sudo service nginx start

**11 — Check if passenger is confugured correctly **

sudo /usr/bin/passenger-config validate-install

12 — Update the Nginx configuration

=> To point Passenger to the version of Ruby that we’re using

$ sudo vim /etc/nginx/conf.d/mod-http-passenger.conf
$ passenger_ruby /home/deploy/.rbenv/shims/ruby; (change the passenger_ruby line to point to your ruby executable) 
$ sudo service nginx restart

13 — Install & Configure Mysql


   $ sudo apt-get install mysql-server mysql-client libmysqlclient-dev

Get Mysql to use mysql_native_password

  $ sudo mysql -u root
  $ USE mysql;
  $ SELECT User, Host, plugin FROM mysql.user;
  $ UPDATE user SET plugin='mysql_native_password' WHERE User='root';
  $ exit

Reset Mysql root password

  $ mysql -u root
  $ USE mysql;
  $ UPDATE user SET authentication_string=PASSWORD('NEW_PASSWORD') WHERE user='root';
  $ exit

Create & Setup new DB


Install Mysql timeszone support

This is in order to use groupdate for Chartkick on AdminPanel of Quickrails boilerplate.

$ mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p --force mysql

Just ignore the warning/error. Then, to see if it’s working, run this command below:

SELECT CONVERT_TZ(NOW(), '+00:00', 'Etc/UTC')

If the timezone is not NULL, then it is working fine.

14 — Setup Capistrano

Open config/deploy.rb, and change these details to yours:

set :application, ‘YOURAPP’
set :repo_url, 'YOURAPP REPO SSH URL’
set :deploy_to, '/home/deploy/YOURAPP'

Open config/deploy/production.rb, and replace the ip with your Droplet IP:

server `YOUR DROPLET IP`, user: 'deploy', roles: %w{web app db}

15 — Setup live/production URL

Open config/db/seeds.rb file, and find “live_url” option under site_setting, and replace the option with your IP/domain name:

live_url: "https://boilerplate.quickrails.com"

16 — Deploy

  • Commit the changes & push update to your repo
  • $ cap production deploy
  • The first deployment will `failed`. Ignore this and continue to Step 15

17 — Create .yml Files

SSH into your server, then go to: YOURAPP/shared/config

Create two new files:

$ touch database.yml
$ touch secrets.yml

Copy the files content from your machine to these files on your Droplet:


     adapter: mysql2
     database: quickrails_production
     username: quickrails
     password: password
     pool: 5
     encoding: utf8mb4 #support_emoji
     collation: utf8mb4_unicode_ci #support_emoji


  secret_key_base: YOURSECRETKEYBASE 

(run “rake secret” on your machine to get the random secret key and copy it over)

**18 — Deploy again and Restart your Nginx **

$ cap production deploy
$ sudo service nginx restart

19 — Migrate Initial data into DB

$ cd app_name/current/shared/config
$ sudo vim database.yml
$ press “I” to edit the file
$ change “production:” into “development:”
$ press “esc”, then type “wq!” to save
$ cd app_name/current
$ rake db:seed

Go back to database.yml and change “development:” back to “production:”

20 — Restart your Server (if needed)

$ sudo poweroff

Go to your Digital Ocean account, and turn your server back on

21 — Install Redis server (If you’re using Quickrails Boilerplate) **

$ sudo apt install redis-server 
$ redis-server

22 — Create SWAP Space on Ubuntu


23 — Fix Possible error

Capfile locked at 3.6.1, but 3.7.1 is loaded

Go to config/deploy.rb , and change the line below: lock '3.6.1'

Uglifier::Error: Unexpected token: keyword (const). To use ES6 syntax, harmony mode must be enabled with Uglifier.new(:harmony => true)

Go to production.rb and replace:

config.assets.js_compressor = :uglifier


config.assets.js_compressor = Uglifier.new(harmony: true)

No video for this post.

No issues for this post.

by ryzalyusoff