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
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
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: