Skip to content

Instantly share code, notes, and snippets.

@orendon
Last active September 26, 2020 21:37
Show Gist options
  • Save orendon/a16ea85c789d520bfc18 to your computer and use it in GitHub Desktop.
Save orendon/a16ea85c789d520bfc18 to your computer and use it in GitHub Desktop.
Bare Metal Linux - Rails Capistrano - Nginx + Passenger tux

Ubuntu 14.04 - Capistrano - Nginx + Passenger

Sample app on: https://github.com/medellinrb/capistrano-workshop

1. Create droplet (don´t forget ssh keys)

ssh-keygen -t rsa -C "[email protected]"
pbcopy < ~/.ssh/bandolero_rsa.pub

2. SSH your server

ssh [email protected] -i ~/.ssh/bandolero_rsa

Add deployer user

groupadd admin
useradd deployer -G admin -m -s /bin/bash
passwd deployer

3. Install all the things

Ruby & dependencies

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 python-software-properties libffi-dev

# Qt and xvfb-run for Capybara Webkit
sudo apt-get install -y libqtwebkit-dev xvfb

# ImageMagick and Rmagick
sudo apt-get install -y imagemagick libmagickwand-dev

SQLite, Git and Node.js

sudo apt-get install -y libsqlite3-dev git nodejs

RVM

sudo apt-get install libgdbm-dev libncurses5-dev automake libtool bison libffi-dev
# Download keys if needed
# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
curl -L https://get.rvm.io | bash -s stable
source ~/.rvm/scripts/rvm
rvm install 2.2.0
rvm use 2.2.0 --default
ruby -v

Nginx and Passenger (from Phusion repository)

# Add HTTPS support for APT if needed
# sudo apt-get install apt-transport-https

# Download Phusion PGP keys
gpg --keyserver keyserver.ubuntu.com --recv-keys 561F9B9CAC40B2F7
gpg --armor --export 561F9B9CAC40B2F7 | sudo apt-key add -

# Add phusion repositories
sudo sh -c "echo 'deb https://oss-binaries.phusionpassenger.com/apt/passenger trusty main' >> /etc/apt/sources.list.d/passenger.list"
sudo chown root: /etc/apt/sources.list.d/passenger.list
sudo chmod 600 /etc/apt/sources.list.d/passenger.list

# Install nginx and passenger
sudo apt-get update
sudo apt-get install nginx-full passenger

4. Configure

Nginx config

# sudo vim /etc/nginx/nginx.conf` and uncomment as needed:
passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /usr/bin/ruby;
# passenger_ruby /home/deployer/.rvm/wrappers/ruby-2.2.0/ruby; # If using rvm
# passenger_ruby /home/deployer/.rbenv/shims/ruby; # If using rbenv

Database

Ubuntu comes with Postgres 9.3, in order to use 9.4:

  • Create the file /etc/apt/sources.list.d/pgdg.list, and add a line for the repository: deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main
  • Import the repository signing key, and update the package lists
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
  sudo apt-key add -
sudo apt-get update
# sudo apt-get install mysql-server mysql-client libmysqlclient-dev
sudo apt-get install postgresql-9.4 postgresql-contrib libpq-dev

sudo su - postgres
createuser USERNAME --pwprompt
exit

# sudo sudo -u postgres psql -1 -c "CREATE USER pgadmin WITH PASSWORD 'secret';"
# sudo sudo -u postgres psql -1 -c "ALTER USER pgadmin WITH SUPERUSER;"
# sudo sudo -u postgres psql -1 -c "CREATE DATABASE awesomeapp_prod;"

DB trouble

  • Check PG port with netstat -an |grep 5432
  • Change pg_hba authentication mode from peer to md5 if needed

5. Capistrano

Gems

group :development do
  # ....

  gem 'capistrano'
  gem 'capistrano-rails'
  gem 'capistrano-bundler'
  # gem 'capistrano-rbenv'
  gem 'capistrano-rvm'
  gem 'capistrano-passenger'
end

bundle install
bundle --binstubs
cap --install

Config

Capfile

# Load DSL and set up stages
require 'capistrano/setup'

require 'capistrano/deploy'
require 'capistrano/rvm'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/passenger'

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

config/deploy.rb

lock '3.4.0'

set :application, 'awesomeapp'
set :repo_url, '[email protected]:Mardiniii/scrapping-workshop.git'

# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp

set :deploy_to, '/home/deployer/awesomeapp'
set :scm, :git
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
set :keep_releases, 5

namespace :deploy do

  # Not needed if using capistrano-passenger gem/recipe
  # desc 'Restart application'
  # task :restart do
  #   on roles(:app), in: :sequence, wait: 5 do
  #     execute :touch, release_path.join('tmp/restart.txt')
  #   end
  # end

  after :publishing, 'deploy:restart'
  after :finishing, 'deploy:cleanup'
end

config/deplot/production.rb

server '104.236.76.72', user: 'deployer', roles: %w{app db web}

6. Latest server configs

Tell nginx about capistrano app folder

/etc/nginx/sites-enabled/default

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

        # server_name mydomain.com;
        server_name localhost;
        passenger_enabled on;
        rails_env    production;
        root         /home/deployer/awesomeapp/current/public;

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

Create Linked files

/home/deployer/awesomewapp/shared/config/database.yml

pg: &pg
  adapter: postgresql
  encoding: unicode
  username: pgadmin
  password: secret
  host: localhost
  pool: 5

production:
  <<: *pg
  database: awesomeapp_prod

/home/deployer/awesomewapp/shared/config/secrets.yml

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

7. Deploy

cap production deploy
cap production deploy:restart
cap -T
@marklocklear
Copy link

Nice write up Oscar!

@marklocklear
Copy link

marklocklear commented Aug 3, 2018

You may run into an issue in the nginx/passenger section where you get a message about unmet dependencies. If so check out https://stackoverflow.com/questions/28818597/nginx-and-passenger-dependencies-issue-digital-ocean-deployment. The first answer should fix the issue however be aware the nginx passenger modules may not be installed here which can cause passenger not to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment