Skip to main content

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.