Run Ruby Applications
This article describes the recommended setup on how to run Ruby applications on Nine's managed servers.
Docker Container
If you want to run your application in a container on a managed server, please refer to the manual about Podman.
Classic Setup
1. Install rbenv Version Manager
We recommend using a Ruby version manager like rbenv to be able to use different Ruby versions than provided by the distribution release of Ubuntu.
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
2. Install Ruby Version
Now we're able to install the desired Ruby version (here 3.0.2):
rbenv install 3.0.2
If you're application requires a global Gem, like Rails, you can also install it now:
rbenv exec gem install rails
3. Deploy Application
The steps to deploy your application depend on your application. With rails, you'd need to compile the assets, then upload everything to the server and install the ruby dependencies:
Run those commands on your local machine
Compile assets:
RAILS_ENV=production bundle exec rake assets:precompile
Copy files to server:
rsync -a -v --delete --exclude='node_modules/*' --exclude='tmp/*' --exclude='vendor/*' --exclude='.git/*' ./ www-data@server.nine.ch:app/current
Ensure dependencies are installed:
ssh www-data@server.nine.ch 'cd ~/app/current && ENV=production rbenv exec bundle install'
4. Setup systemd Service
To ensure a service keeps running, e.g. is restarted if it fails or on a system restart, we recommend using a systemd user service.
This example loads environment variables from ~/app/env
and then executes rails server -b localhost --log-to-stdout
in the directory ~/app/current
.
The command depends on your setup. The above example assumes that you're running a rails app.
Create the service file in ~/.config/systemd/user/rails-app.service
.
[Unit]
Description=Application
After=network.target
[Service]
Type=simple
WorkingDirectory=%h/app/current
Environment=RAILS_ENV=production
Environment=PORT=3000
EnvironmentFile=%h/app/env
ExecStart=/usr/bin/rbenv exec rails server -b localhost --log-to-stdout
TimeoutSec=15
Restart=on-failure
[Install]
WantedBy=default.target
And then start the service:
touch ~/app/env # ensure environment file exists
systemctl --user daemon-reload
systemctl --user enable rails-app.service
systemctl --user start rails-app.service
Your application should now be registered as service and already running:
$ systemctl --user status rails-app.service
● rails-app.service - Application
Loaded: loaded (/home/www-data/.config/systemd/user/rails-app.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2021-07-16 10:13:36 CEST; 5s ago
Main PID: 3615317 (ruby)
CGroup: /user.slice/user-33.slice/user@33.service/rails-app.service
└─3615317 puma 5.3.2 (tcp://localhost:3000) [current]
Jul 16 10:13:37 server rbenv[3615317]: => Run `bin/rails server --help` for more startup options
Jul 16 10:13:37 server rbenv[3615317]: Puma starting in single mode...
Jul 16 10:13:37 server rbenv[3615317]: * Puma version: 5.3.2 (ruby 3.0.2-p107) ("Sweetnighter")
Jul 16 10:13:37 server rbenv[3615317]: * Min threads: 5
Jul 16 10:13:37 server rbenv[3615317]: * Max threads: 5
Jul 16 10:13:37 server rbenv[3615317]: * Environment: production
Jul 16 10:13:37 server rbenv[3615317]: * PID: 3615317
Jul 16 10:13:37 server rbenv[3615317]: * Listening on http://127.0.0.1:3000
Jul 16 10:13:37 server rbenv[3615317]: * Listening on http://[::1]:3000
Jul 16 10:13:38 server rbenv[3615317]: Use Ctrl-C to stop
5. Configure Webserver
The application is now running on the local port 3000. To configure the web server, we use the CLI tool nine-manage-vhosts
(you can find more information in the dedicated support article).
For this use case, we created the templates proxy
and proxy_letsencrypt
.
To enable SSL/TLS, use the proxy_letsencrypt
template.
To access your application via the existing webserver, you need to pass the PROXYPORT
variable as parameter for --template-variable
.
sudo nine-manage-vhosts virtual-host create example.com --template proxy --template-variable PROXYPORT=3000 --webroot ~/app/current/public
Virtual Host created: example.com
example.com
===========
DOMAIN: example.com
USER: www-data
WEBROOT: /home/www-data/app/current/public
TEMPLATE: proxy
TEMPLATE VARIABLES: PROXYPORT
3000
ALIASES: www.example.com
example.com.server.nine.ch
To see the configuration, use:sudo nine-manage-vhosts virtual-host show example.com
Afterwards, your application should be accessible via port 80 or 443.