Cannot create systemd script for Puma

5.4k Views Asked by At

I created a service script named "puma.service" in /etc/systemd/system/ with the following contents:

[Unit]
Description=Puma HTTP Server
After=network.target

[Service]
Type=simple

User=ubuntu

WorkingDirectory=/home/username/appdir/current

ExecStart=/bin/bash -lc "/home/username/appdir/current/sbin/puma -C /home/username/appdir/current/config/puma.rb /home/username/appdir/current/config.ru"

Restart=always

[Install]
WantedBy=multi-user.target

I enabled the service and when started, I'm getting the following log from systemctl:

● puma.service - Puma HTTP Server
   Loaded: loaded (/etc/systemd/system/puma.service; enabled; vendor preset: enabled)
   Active: inactive (dead) (Result: exit-code) since Wed 2016-12-14 10:09:46 UTC; 12min ago
  Process: 16889 ExecStart=/bin/bash -lc cd /home/username/appdir/current && bundle exec puma -C /home/username/appdir..
 Main PID: 16889 (code=exited, status=127)

Dec 14 10:09:46 ip-172-31-29-40 systemd[1]: puma.service: Main process exited, code=exited, status=127/n/a
Dec 14 10:09:46 ip-172-31-29-40 systemd[1]: puma.service: Unit entered failed state.
Dec 14 10:09:46 ip-172-31-29-40 systemd[1]: puma.service: Failed with result 'exit-code'.
Dec 14 10:09:46 ip-172-31-29-40 systemd[1]: puma.service: Service hold-off time over, scheduling restart.
Dec 14 10:09:46 ip-172-31-29-40 systemd[1]: Stopped Puma HTTP Server.
Dec 14 10:09:46 ip-172-31-29-40 systemd[1]: puma.service: Start request repeated too quickly.
Dec 14 10:09:46 ip-172-31-29-40 systemd[1]: Failed to start Puma HTTP Server.

Although, when I give the command in SSH terminal the server started and was running perfect. Is there any changes I have to make in the service file?

Note:

  1. I have changed the dirnames for your convenience.
  2. I did some research and the cause of status 127 is due to the executable not in the path. But, I guess that won't be a problem.

Can you shed some light?

3

There are 3 best solutions below

4
On BEST ANSWER

I found the problem and changed the ExecStart as mentioned below and it worked like a charm:

ExecStart=/home/username/.rbenv/shims/bundle exec puma -e production -C ./config/puma.rb config.ru
PIDFile=/home/username/appdir/shared/tmp/pids/puma.pid

bundle should be taken from the rbenv shims and also the puma's config file (config/puma.rb) and application's config file (config.ru) can be given in relative path.

0
On

For rvm users try with

[Unit]
Description=Puma HTTP Server
After=network.target

[Service]
Type=simple
User=user_name
Group=user_name

WorkingDirectory=/home/user_name/apps/app_name/current
Environment=RAILS_ENV=production

ExecStart=/home/user_name/.rvm/bin/rvm ruby-3.1.2@app_name do bundle exec --keep-file-descriptors puma -C /home/user_name/apps/app_name/current/config/puma/production.rb
ExecReload=/bin/kill -USR1 $MAINPID

StandardOutput=append:/home/user_name/apps/app_name/current/log/puma_access.log
StandardError=append:/home/user_name/apps/app_name/current/log/puma_error.log
SyslogIdentifier=app_name-puma

Restart=always
KillMode=process


[Install]
WantedBy=multi-user.target


if you are not using a gemset change

ExecStart=/home/user_name/.rvm/bin/rvm ruby-3.1.2@app_name ....

to

ExecStart=/home/user_name/.rvm/bin/rvm default
0
On

One way to solve it is to specify a PID file and systemd will take a look at that file to check on service status.

Here's how we use this in our scripts (adapted to your given sample)

ExecStart=/bin/bash -lc '/home/username/appdir/current/sbin/puma -C /home/username/appdir/current/config/puma.rb /home/username/appdir/current/config.ru --pidfile /home/username/appdir/current/tmp/pids/puma.pid'
PIDFile=/home/username/appdir/current/tmp/pids/puma.pid

Take note that you might have to configure --pidfile via your -C puma.rb file instead of passing it an as parameter. I'm just showing it here to illustrate that --pidfile (in puma config) should be the same as PIDFile in the service file.

As for why the error message is that way, I'm not sure myself and is interested in the answer too.