jookyboi of Team Cacher
10/6/2019 - 10:42 PM

DigitalOcean Rails/Ubuntu/NGINX (16.04) Setup

DigitalOcean Rails/Ubuntu/NGINX (16.04) Setup

  1. Setup
  2. Swapfile
  3. NGINX
  4. ElasticSearch
  5. RVM
  6. Rails
  7. Postgres
  8. Capistrano
  9. Let's Encrypt
  10. Firewall


Create a new, start with the smallest droplet. Use Ubuntu 16.04, log in as root.

1. Create non-root user 'rails'

Initial Server Setup with Ubuntu 16.04

create user 'rails'

adduser rails

Add to sudoers group

usermod -aG sudo rails

Switch user to 'rails'

su - rails

Create ssh key


Create sym link for webroot

cd ~
ln -s /var/www/html html

2. Swapfile

How To Add Swap Space on Ubuntu 16.04

Check swapfile

free -h

Check freespace

df -h

Create a 4gb Swap File

sudo fallocate -l 4G /swapfile


ls -lh /swapfile

Lock it down

sudo chmod 600 /swapfile

Make it swap

sudo mkswap /swapfile

Enable it

sudo swapon /swapfile


sudo swapon --show

Check swapfile

free -h

Make it permanent

sudo cp /etc/fstab /etc/fstab.bak;
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab


How To Install Nginx on Ubuntu 16.04

Install NGINX

sudo apt-get update
sudo apt-get install nginx

Check status

systemctl status nginx

Tweak UFW firewall

sudo ufw allow 'OpenSSH'
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status

Install CURL, get your IP, and check that you can request a page in your browser!

sudo apt-get install curl
curl -4


sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx

Server Configuration

/etc/nginx - The nginx configuration directory. All of the Nginx configuration files reside here.

/etc/nginx/nginx.conf The main Nginx configuration file. This can be modified to make changes to the Nginx global configuration.

/etc/nginx/sites-available/ The directory where per-site "server blocks" can be stored. Nginx will not use the configuration files found in this directory unless they are linked to the sites-enabled directory (see below). Typically, all server block configuration is done in this directory, and then enabled by linking to the other directory.

/etc/nginx/sites-enabled/ The directory where enabled per-site "server blocks" are stored. Typically, these are created by linking to configuration files found in the sites-available directory.

/etc/nginx/snippets This directory contains configuration fragments that can be included elsewhere in the Nginx configuration. Potentially repeatable configuration segments are good candidates for refactoring into snippets.

Server Logs

/var/log/nginx/access.log Every request to your web server is recorded in this log file unless Nginx is configured to do otherwise.

/var/log/nginx/error.log Any Nginx errors will be recorded in this log.

4. ElasticSearch

How To Install and Configure Elasticsearch on Ubuntu 16.04 Elastic search requires at least 2GB of ram to work for some reason.

Install JAVA

sudo add-apt-repository ppa:webupd8team/java
sudo apt-get install oracle-java8-installer

Get ElasticSearch

sudo apt-get update


sudo dpkg -i elasticsearch-5.4.0.deb

Remove DEB file

rm elasticsearch-5.4.0.deb


sudo systemctl enable elasticsearch.service


sudo nano /etc/elasticsearch/elasticsearch.yml

Edit Config File

... mycluster1 "My First Node"


sudo systemctl start elasticsearch.service

Tweak UFW firewall

sudo ufw allow from to any port 9200
sudo ufw status


curl -X GET 'http://localhost:9200'


sudo systemctl status elasticsearch.service

5. RVM

How To Install Ruby on Rails with RVM on Ubuntu 16.04

Add key

gpg --keyserver hkp:// --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

Move to a writeable directory

cd /tmp

Get latest Ruby

curl -sSL -o


cat /tmp/ | bash -s stable --rails

Reload your source file

source /etc/profile.d/

Install your Ruby VERSION

rvm install VERSION --default

6. Rails

Deploying a Rails App on Ubuntu 14.04 with Capistrano, Nginx, and Puma

Install Rails and bundler

gem install rails -v '5.0.1' -V --no-ri --no-rdoc
gem install bundler -V --no-ri --no-rdoc

Authorize your server to read from your repo, you'll have to add a deployment key to your repo. To do this you must copy your ~/.ssh/ file to your repo (make sure this is your deployment user, eg. rails)

ssh -T
ssh -T
ssh -T

Change Permissions on html directory

sudo chown rails:rails /var/www/html/

Clone repo

git clone

Add your local key to the server, if this doesn't work just add your local public key ( to /home/rails/.ssh/authorized_keys


7. Postgres

How To Install and Use PostgreSQL on Ubuntu 16.04

Install Postgres

sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

Create 'rails' postgres user

sudo -i -u postgres
createuser --interactive

Make it look like this:

Enter name of role to add: rails
Shall the new role be a superuser? (y/n) y

Create the database for rails user

createdb rails

libpq has to be installed separately

sudo apt-get install libpq-dev

8. Capistrano

Add gems to deployment

group :development do
  gem 'capistrano'
  gem 'capistrano-rails'
  gem 'capistrano-rvm'
  gem 'capistrano3-puma', github: 'seuros/capistrano-puma'
  gem 'capistrano-bundler'
  gem 'capistrano-rails-console'

Install Capistrano

cap install


require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rails'
require 'capistrano/rvm'
require 'capistrano/bundler'
require 'capistrano/puma'
require 'capistrano/scm/git'
require 'capistrano/rails/console'

set :rvm_type, :user
set :rvm_ruby_version, '2.3.1'
install_plugin Capistrano::Puma
install_plugin Capistrano::SCM::Git
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

Deploy.rb, replace (APP_NAME)

lock "3.8.1"

set :application, "APP_NAME"
set :repo_url, ""
set :deploy_to, "/home/rails/html"
set :pty, true
set :puma_conf, "#{shared_path}/config/puma.rb"

append :linked_files, "config/database.yml", "config/secrets.yml", ".env"
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"

Production.rb, replace SERVER_IP

server 'SERVER_IP', user: 'rails', roles: %w{app db web}

Create shared config files

mkdir -p /var/www/html/shared/config
touch /var/www/html/shared/config/database.yml
touch /var/www/html/shared/config/secrets.yml
touch /var/www/html/shared/config/puma.rb
touch  /home/rails/html/shared/.env

Copy config in databse.yml

  adapter: postgresql
  encoding: unicode
  pool: 5
  database: APP_PRODUCTION
  username: rails
  url: localhost
  password: <%= ENV['DATABASE_PASSWORD'] %>

Copy config into secrets.yml

  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

Copy config into .env


Copy config in puma.rb

#!/usr/bin/env puma

directory '/home/rails/html/current'
rackup "/home/rails/html/current/"
environment 'production'

tag ''

pidfile "/home/rails/html/shared/tmp/pids/"
state_path "/home/rails/html/shared/tmp/pids/puma.state"
stdout_redirect '/home/rails/html/shared/log/puma_access.log', '/home/rails/html/shared/log/puma_error.log', true

threads 0,16

bind 'unix:///home/rails/html/shared/tmp/sockets/puma.sock'

workers 0


on_restart do
  puts 'Refreshing Gemfile'
  ENV["BUNDLE_GEMFILE"] = "/home/rails/html/current/Gemfile"

May need Node.js for Javascript Runtime

sudo apt-get install nodejs

9 Let's Encrypt

How To Secure Nginx with Let's Encrypt on Ubuntu 16.04

Install Certbot

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot


sudo nano /etc/nginx/sites-available/default

Inside the server block, add this location block

  location ~ /.well-known {
    allow all;

Check your NGINX config file

sudo nginx -t

Restart NGINX

sudo systemctl restart nginx

Get your cert (make sure you know your webroot)

sudo certbot certonly --webroot --webroot-path=/var/www/html -d -d

Generate strong diff

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Create configuration snippet

sudo nano /etc/nginx/snippets/

Paste in your certificates

ssl_certificate /etc/letsencrypt/live/;
ssl_certificate_key /etc/letsencrypt/live/;

Create strong encryption params

sudo nano /etc/nginx/snippets/ssl-params.conf

Paste in params

# from
# and

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver valid=300s;
resolver_timeout 5s;
# disable HSTS header for now
#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

Nginx Server finalization

How To Secure Nginx with Let's Encrypt on Ubuntu 16.04

create a new Nginx config file

touch /etc/nginx/sites-available/rails
chmod 644 rails

Update your APPLICATIONSOCKET.sock, server_name, snippet location

upstream app_server {
    server unix:///home/rails/html/shared/tmp/sockets/APPLICATIONSOCKET.sock fail_timeout=0;

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name EXAMPLE.COM;
    return 301 https://$server_name$request_uri;

server {
    # SSL configuration
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    include snippets/;
    include snippets/ssl-params.conf;

    root /home/rails/html/current/public;

    index index.htm index.html;

    location / {
        try_files $uri/index.html $uri.html $uri @app;

    location ~* ^.+\.(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|mp3|flv|mpeg|avi)$ {
        try_files $uri @app;

    location @app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://app_server;

    location ~ /.well-known {
        allow all;

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;

Update symobolic link

cd /etc/nginx/sites-enabled
rm default
ln -s /etc/nginx/sites-available/rails default

Restart NGINX

sudo systemctl restart nginx