08.21.2019
Deploy rails app with puma, systemd and nginx
This article will show how to deploy rails app using puma and systemd as daemon with nginx
In other article I did show how to install ruby, you can follow to install ruby on your server
In this article I will deploy my rails app using ubuntu user named ubuntu
su ubuntu
cd
exec bash
git clone [url-to-your-remote]/myrailsapp
cd myrailsapp
bundle install
Edit database config to make sure your app can connect database
vim config/database.yml
In production part edit as below:
database: <%= ENV['DATABASE_NAME'] %>
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
edit puma.rb file, paste below code at the end of puma.rb file
# Change to match your CPU core count
workers 2
# Min and Max threads per worker
threads 1, 6
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
# Default to production
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env
# Set up socket location
bind "unix://#{shared_dir}/sockets/puma.sock"
# Logging
stdout_redirect "#{shared_dir}/log/puma.stdout.log",
"#{shared_dir}/log/puma.stderr.log", true
# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"
activate_control_app
on_worker_boot do
require "active_record"
ActiveRecord::Base.connection.disconnect! rescue
ActiveRecord::ConnectionNotEstablished
ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
end
Next, create puma share directory
mkdir shared
cd shared
mkdir sockets pids log
Export environment config
export DATABASE_NAME=database
export DATABASE_USERNAME=databaseusername
export DATABASE_PASSWORD="databasepassword"
export RAILS_ENV=production
Run test to make sure puma can run correctly
bundle exec puma -C config/puma.rb
Ctrl + C to stop server
auto export config each time you logout from current user
cd ~
vim .bashrc
Add these content at the end of file
export DATABASE_NAME=database
export DATABASE_USERNAME=databaseusername
export DATABASE_PASSWORD="databasepassword"
export RAILS_ENV=production
then run
source .bashrc
* if you got command not found error, please remove a space after export keyword then insert a new space
cd ~/myrailsapp
bundle exec rails db:create
bundle exec rails db:migrate
bundle exec rails assets:precompile
# if your got error "There was an error while trying to load the
gem 'uglifier'.". Please install nodejs
bundle exec rails secret
Copy secret key then paste into config/secret.yml
production:
secret_key_base: [secret key]
Create systemd service
exit from current user
exit
now you are running as root permission
vim /etc/systemd/system/puma.service
then past below content, remember to change working directory to your rails app and database config
[Unit]
Description=myrailsapp-web
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/myrailsapp
Environment="RAILS_ENV=production"
Environment="DATABASE_NAME=databasename"
Environment="DATABASE_USERNAME=mysqlusername"
Environment="DATABASE_PASSWORD=mysqlpassword"
Environment="PORT=3000"
ExecStart=/home/ubuntu/.rbenv/shims/bundle exec puma -C config/puma.rb
TimeoutSec=15
Restart=always
[Install]
WantedBy=multi-user.target
Save and exit
add source path to puma.conf
vim /etc/puma.conf
Add path to your source code
/home/ubuntu/myrailsapp
Save and exit
service puma start
Make sure you have puma.sock in shared/sockets
ls /home/ubuntu/myrailsapp/shared/sockets
Config nginx
vim /etc/nginx/site-available/myrailsapp
Paste below content, remember to correct unix path to your puma.sock, root directory and domain name
upstream app {
# Path to Puma SOCK file, as defined previously
server unix:///home/ubuntu/myrailsapp/shared/sockets/puma.sock
fail_timeout=0;
}
server {
listen 80;
server_name myrailsapp.com;
root /home/ubuntu/myrailsapp/public;
try_files $uri/index.html $uri @app;
location / {
try_files $uri $uri @app;
}
location @app {
proxy_pass http://app;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
create symbolic link to enable config file
cd /etc/nginx/site-enabled
ln -s /etc/nginx/site-available/myrailsapp
nginx -t
service nginx restart
service puma restart
Now check your website on browser
Hope this help
Please leave a comment if you have any problem when deploy your rails app