Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save fzrhrs/c96561a7db7123a07e08e1c9537b7cec to your computer and use it in GitHub Desktop.
Save fzrhrs/c96561a7db7123a07e08e1c9537b7cec to your computer and use it in GitHub Desktop.
Part 3 of 3: Rails Deployment Ubuntu 2404 (2024)

Now, the final part of the initial deployment for Rails with RVM, Postgres, Ubuntu, NGINX, Capistrano, Puma 6 & Systemd.

Go to /etc/nginx/sites-available

Create a conf file, I usually name it after my app. For this tutorial, let's call it "website":

upstream puma_website {
  server unix:///home/deploy/website/shared/sockets/puma.sock;
}

server {
  listen 80;
  server_name website.com;

  root /home/deploy/website/current/public;
  access_log /home/deploy/website/current/log/nginx.access.log;
  error_log /home/deploy/website/current/log/nginx.error.log info;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @puma_website;
  location @puma_website {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://puma_website;
  }

  location /cable {
    proxy_pass http://puma_website/cable;
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;
}

Copy this sample and change the application name accordingly. The fastest to do it is by opening the file using vi, and then use this. While in ESC mode, type:

:%s/oldtext/newtext/gc

Adding 'c' at the end of the command will confirm each replacement before it is applied.

Check if all is good:

sudo nginx -t

If all is good, then do a symlink to /etc/nginx/sites-enabled. I usually go to the folder first, and create a symlink from there.

Assuming you are in the directory, do:

sudo ln -s ../sites-available/website .

Then, restart nginx. Out of habit, I do this one bye one:

sudo service nginx stop
sudo service nginx start
sudo service nginx status

But you can also do this in one command:

sudo service nginx restart

If you haven't run this command, please do so before continuing:

bundle exec cap production puma:install

Read more about this here: https://github.com/seuros/capistrano-puma

1. Create puma.rb

Ensure in your application folder, specifically app_name/shared, you create a file called puma.rb. In it, it should have this content:

#!/usr/bin/env puma

directory '/home/deploy/website/current'
rackup "/home/deploy/website/current/config.ru"
environment 'production'

tag ''

pidfile "/home/deploy/website/shared/tmp/pids/puma.pid"
state_path "/home/deploy/website/shared/tmp/pids/puma.state"
stdout_redirect '/home/deploy/website/shared/log/puma_access.log', '/home/deploy/website/shared/log/puma_error.log', true

threads 0, 16

bind 'unix:///home/deploy/website/shared/sockets/puma.sock'

workers 0

restart_command 'bundle exec puma'

prune_bundler

on_restart do
  puts 'Refreshing Gemfile'
  ENV["BUNDLE_GEMFILE"] = ""
end

2. Create service file.

Assuming your EC2 instance hosts multiple applications, you'll want to create separate systemd service files for each Puma instance. This way, each app can be managed independently, and changes to one service won't affect the others.

This will also work even if you only have one application in the instance.

For each application, you should create a unique service file. For example, if your current app is website, create a service file named website_puma_production.service:

sudo vi /etc/systemd/system/website_puma_production.service

Here's what the service file look like for website:

[Unit]
Description=Puma HTTP Server for website
After=network.target

[Service]
Type=simple
User=deploy
WorkingDirectory=/home/deploy/website/current
ExecStart=/bin/bash -lc 'bundle exec puma -C /home/deploy/website/shared/puma.rb'
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
  • Naming Convention: Name the service file according to the app it serves (e.g., appname_puma_stage.service).
  • WorkingDirectory: Ensure this points to the correct directory for each application.
  • ExecStart: Adjust this as needed for each application’s configuration.

Reload systemd:

sudo systemctl daemon-reload

Start and enable each service. For example, for website:

sudo systemctl enable website_puma_production
sudo systemctl start website_puma_production

And finally, just to be safe, restart nginx:

sudo systemctl restart nginx

Rails Deployment Ubuntu Series:

  1. Part 1 of 3: Rails Deployment Ubuntu 24.04 (2024)
  2. Part 2 of 3: Rails Deployment Ubuntu 24.04 (2024)
  3. Part 3 of 3: Rails Deployment Ubuntu 2404 (2024)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment