Puma & sidekiq with Systemd

🇬🇧
linux
sidekiq
puma
rails


This article exists in french: https://gdurelle.com/tech/2022/10/16/fr-systemd.html

I won’t re-explain what is systemd.
I’ll only share how to make a project run Rails (7.0) with Puma 5 and Sidekiq 6.

I am not a big fan of systemd, I only use it by obligation. I am not a sysadmin, and to deploy a personnal project online I have basically the choice between metal and cloud.
I chose metal because it let me do what I want without constraints and for lower cost.

Initially Puma launched at deployment via Capistrano, in daemon mode, but version 5 has totally removed that.
Rightfully or wrongfully is not the subject here, we will concentrate on what has to be done.

  1. Services & socket files
  2. Relaunch systemd loader
  3. Enable the files
  4. Boot services

Foreword

For each project on the server, I create a different user. I am therefore in a directory that has the same name as my application: /home/myappli.

To launch a service there is 2 possibilites:

For a service in user mode you have to place service files in a specific place of the user home: ~/.config/systemd/user/

In absolute: /home/myappli/.config/systemd/user/

1. Service files

The naming convention for those files is: myappli_theprogram_env. Try to respect it, it will ease your life with all that is using the default naming.

My Rails application is named: myappli
The environnement is named: staging
And we will launch: puma

The first and most important file is the file .service, so myappli_puma_staging.service

[Unit]
Description=Puma HTTP Server for myappli staging
After=network.target
Requires=myappli_puma_staging.socket

[Service]
Type=simple
Environment=RAILS_ENV=staging
WorkingDirectory=/srv/www/myappli/current/
ExecStart=/home/myappli/.rbenv/shims/puma -e staging -C /srv/www/myappli/shared/puma.rb /srv/www/myappli/current/config.ru
ExecStop=/home/myappli/.rbenv/shims/puma -e staging -C /srv/www/myappli/shared/puma.rb stop
ExecReload=/home/myappli/.rbenv/shims/puma -e staging -C /srv/www/myappli/shared/puma.rb phased-restart

PIDFile=/srv/www/myappli/shared/tmp/pids/puma.pid

Restart=always
RestartSec=8
KillMode=process
SyslogIdentifier=puma

[Install]
WantedBy=multi-user.target

Socket file

myappli_puma_staging.socket

[Unit]
Description=Puma HTTP Server Accept Sockets

[Socket]
ListenStream=0.0.0.0:9294
ListenStream=0.0.0.0:9295

NoDelay=true
ReusePort=true
Backlog=1024

[Install]
WantedBy=sockets.target

2. Relaunch systemd loader

Log as root: systemctl daemon-reload

Enable the files

systemctl enable myappli_puma_env.service myappli_puma_env.socket

Boot services

Go back in user and just type the content of ExecStart, which should worked by itself.

Or even from your local console: cap puma:start