Skip to content

Instantly share code, notes, and snippets.

@newmetl
Last active May 10, 2019 06:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save newmetl/6e83f7b5b4949f5bc4ad7a1fe67439f7 to your computer and use it in GitHub Desktop.
Save newmetl/6e83f7b5b4949f5bc4ad7a1fe67439f7 to your computer and use it in GitHub Desktop.
Setup a Droplet on Digital Ocean for Rails with Nginx, Passenger and Postgresql

Setup new Server

This setup guide was created with the following components:

  • DigitalOcean Droplet (Ubuntu 16.04.4 x64)
  • Postgresql 9.5
  • Nginx + Passenger
  • Rails 5.2
  • Ruby 2.4.1

Create new user

Tutorial for more infos

ssh root@<ip>

adduser rails
mkdir /home/rails/.ssh
touch /home/rails/.ssh/authorized_keys
# Add my ssh key to rails user
nano /home/rails/.ssh/authorized_keys

Give admin rights to rails user

visudo

add under root ALL=(ALL:ALL) ALL

rails    ALL=(ALL:ALL) ALL

save and exit.

Install Nginx

Now exit as root and reconnect with the rails user.

ssh rails@<ip>

sudo apt-get update
sudo apt-get install nginx
# Setup firewall if needed
# But careful! Don't lock yourself out!
# sudo ufw app list
# sudo ufw allow 'Nginx HTTP'
# sudo ufw enable
# sudo ufw status
# systemctl status nginx

Install rvm

ssh rails@<ip>

gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
cd /tmp
curl -sSL https://get.rvm.io -o rvm.sh
cat /tmp/rvm.sh | bash -s stable --rails
source /home/rails/.rvm/scripts/rvm
# rvm list known

Tutorial for more infos

Install Passenger

Tutorial for more infos

As non root user with root privileges ...

ssh rails@<ip>

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 xenial main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update

sudo apt-get install -y nginx-extras passenger

As root, enable the Passenger Nginx module and restart Nginx. Edit /etc/nginx/nginx.conf and uncomment include /etc/nginx/passenger.conf;. For example, you may see this:

include /etc/nginx/passenger.conf;

# http {
#     include /etc/nginx/passenger.conf;
#     ...
# }

In the /etc/nginx/passenger.conf update the passenger_ruby to the ruby version you are using like this:

passenger_ruby /home/rails/.rvm/wrappers/ruby-2.4.1/ruby;

Check installation

sudo /usr/bin/passenger-config validate-install
sudo /usr/sbin/passenger-memory-stats

Nginx Config

Add a new config for the rails app /etc/nginx/sites-available/rails

server {
    listen 80 default_server;
    server_name _;
    index index.htm index.html;

    root /home/rails/production/current/public;
    passenger_friendly_error_pages on;

    passenger_enabled on;
    rails_env    production;

    # serve static content directly
    # location ~* \.(ico|jpg|gif|png|css|js|swf|html)$ {
    location ~* ^/assets {
        if (-f $request_filename) {
        expires max;
        break;
        }
    }

}

Remove the symlink for the default server and create one for the rails app with

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

Restart nginx with

systemctl restart nginx

Create Rails App

When creating a new rails app, make sure to generate it with postgresql right away.

rails new MyRailsApp --database=postgresql

Setup capistrano

Add capistrano gem

group :development do
  gem "capistrano", "~> 3.11", require: false
end

Run bundler

bundle install

Install capistrano

bundle exec cap install

In the Capfile comment in the following lines

require "capistrano/rvm"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/passenger"
require "capistrano/rails/migrations"

Add these gems

gem 'capistrano-rvm'
gem 'capistrano-passenger'

And bundle

bundle

In config/deploy.rb add

set :application, "<YOUR APP NAME>"
set :repo_url, "git@github.com:newmetl/YOUR-REPO.git"
set :passenger_restart_with_touch, true

In config/deploy/production.rb add

server 'ip.to.your.server', user: 'rails', roles: %w(web app db)
set :branch, 'production'
set :application, '<YOUR APP NAME>'
set :deploy_to, '/home/rails/production/'
set :rails_env, :production
set :keep_releases, 5

Create a production branch and push it.

git checkout -b production
git push -u origin production

Run deployment for the first time

bundle exec cap production deploy

Add JS runtime

Comment in this gem

gem 'mini_racer', platforms: :ruby

In the terminal

bundle

Setup Environment Variables

Add to Gemfile

gem 'dotenv-rails'

and run

bundle

Create env file on the server

ssh rails@<ip>
touch ~/.env.production

Now you can fill in your env variables like this

SECRET_KEY_BASE=<your secret key>
MY_RAILS_APP_DATABASE_PASSWORD=<your db password>

and finally, in your application.rb add these lines

require 'dotenv'
Dotenv.load('/home/rails/.env.production') if Rails.env.production?

if you are setting up your production evnironment.

App Secret and Master Key

Add config/secrets.yml with

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

Create new secret with

be rails secret

Add ENV varialble to your env file /home/rails/.env.production

SECRET_KEY_BASE=<your secret key>

Add this line to config/deploy.rb

append :linked_files, %w{config/master.key}

Copy the content of the file config/master.key to

/home/rails/production/shared/config/master.key

Read more about encrypted credentials here

Setup Postgres Database

Tutorial for more info More info

In Capfile uncomment

require "capistrano/rails/migrations"

As rails user

ssh rails@<ip>

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

Create new postgres user for app

sudo -u postgres createuser --interactive

Give the user a name (e.g. railsapp) and all rights.

sudo -u postgres psql
postgres=# \password railsapp

Set password and exit.

postgres=# \q

Create production database for your rails app.

sudo -u postgres createdb -O railsapp MyRailsApp_production

Make sure your database.yml is set up correctly.

production:
    <<: *default
    database: MyRailsApp_production
    host: localhost # use localhost, so the connection is made via network, and not via unix socket.
    username: railsapp
    password: <%= ENV['MY_RAILS_APP_DATABASE_PASSWORD'] %>

Add the password to ~/.env.production

MY_RAILS_APP_DATABASE_PASSWORD=<Your password here>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment