Deploying a production ready Ruby on Rails app on a Linux Server should be the easiest thing in the world. Nevertheless, information on this subject is scarse, outdated or stunningly confusing. Even more so when using a ruby version management system like rbenv or rvm who demand for a user to have a certain environment via the shells startup script.
Puma, the built-in Ruby/Rack web server in Rails 5 is solid and describes itself as "simple, fast, threaded, and highly concurrent". We can safely use it in a production environment and further simplify in dealing with this problem.
Systemd
On many Linux distributions the default system and service manager systemd
offers you the option to run your production app as a service on a silver platter. There's really no need to keep a login shell open and manually run the app. Isn't it just better to simply run it as a service without having to manually interfere and worrying about its state? An apps self-recreation after a reboot or crash gives you peace of mind.
Create the service file
cd /etc/systemd/system
touch MyRailsApp.service
[Unit]
Description=MyRailsApp
After=network.target
[Service]
Type=simple
User={username}
WorkingDirectory={/path/to/app/directory}
ExecStart=/home/{username}/.rbenv/bin/rbenv exec bundle exec rails s -p 4567
Environment="RAILS_ENV=production"
Environment="SECRET_KEY_BASE={secret string}"
Environment="RBENV_ROOT=/home/{username}/.rbenv"
Environment="NODENV_ROOT=/home/{username}/.nodenv"
Environment="PATH=/home/{username}/.rbenv/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
TimeoutSec=30
RestartSec=15s
Restart=always
[Install]
WantedBy=multi-user.target
Run the service
# Run these
systemctl daemon-reload
systemctl restart MyRailsApp
systemctl status MyRailsApp
# Get that
● MyRailsApp.service - MyRailsApp
Loaded: loaded (/etc/systemd/system/MyRailsApp.service; enabled; vendor preset: disabled) Active: active (running) since Mon 2017-11-13 21:25:27 CET; 10s ago
Main PID: 28757 (ruby)
CGroup: /system.slice/MyRailsApp.service
└─28757 puma 3.10.0 (tcp://0.0.0.0:4567) [MyRailsApp]
Nov 13 21:25:27 phoenix systemd[1]: Starting MyRailsApp...
Nov 13 21:25:38 phoenix rbenv[28757]: => Booting Puma
Nov 13 21:25:38 phoenix rbenv[28757]: => Rails 5.1.4 application starting in production
Nov 13 21:25:38 phoenix rbenv[28757]: => Run `rails server -h` for more startup options
Nov 13 21:25:38 phoenix rbenv[28757]: Puma starting in single mode...
Nov 13 21:25:38 phoenix rbenv[28757]: * Version 3.10.0 (ruby 2.4.2-p198), codename: Russell\'s Teapot
Nov 13 21:25:38 phoenix rbenv[28757]: * Min threads: 5, max threads: 5
Nov 13 21:25:38 phoenix rbenv[28757]: * Environment: production
Nov 13 21:25:38 phoenix rbenv[28757]: * Listening on tcp://0.0.0.0:4567
Nov 13 21:25:38 phoenix rbenv[28757]: Use Ctrl-C to stop
Apache Reverse Proxy Configuration
<Macro RailsProd $servername $folder $port>
<VirtualHost *:80>
ServerName $servername
Redirect permanent / https://$servername/
</VirtualHost>
<VirtualHost *:443>
ServerName $servername
DocumentRoot "$folder/public/"
<Location />
Require all granted
Options FollowSymLinks
AllowOverride None
# MultiViews must be turned off.
Order allow,deny
Allow from all
</Location>
ProxyPass /favicon.ico !
ProxyPass /robots.txt !
ProxyPassMatch ^/(404|422|500).html$ !
ProxyPass /assets/ !
ProxyPass /fonts/ !
ProxyPass /static/ !
ProxyPass / http://127.0.0.1:$port/
ProxyPassReverse / http://127.0.0.1:$port/
ErrorLog "/etc/httpd/logs/$servername_error.log"
CustomLog "/etc/httpd/logs/$servername_access.log" common
Include /etc/httpd/conf/include_ssl.conf
SSLCertificateFile /etc/letsencrypt/live/$servername/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/$servername/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/$servername/chain.pem
Header always set X-Xss-Protection "0"
</VirtualHost>
</Macro>
###################################################################################
# local servername folder port
Use RailsProd myrailsapp.com /path/to/myrailsapp 4567