简体   繁体   中英

How to get systemd to restart Rails App with Puma

I've been struggling with this a week now and really can't seem to find an answer. I've deployed my Rails App with Capistrano. I use Puma as a server.

When I deploy, everything works ok. The problem is to get Puma to start at reboot and/or when it crashes.

To get the deployment setup, I've used this tutorial . I'm also using RVM. The problem I seem to get is to get the service to start Puma. Here's what I've used (service file):

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

[Service]
Type=simple

#User=my-user

WorkingDirectory=/home/my-user/apps/MyApp/current

ExecStart=/home/my-user/apps/MyApp/current/sbin/puma -C /home/my-user/apps/MyApp/shared/puma.rb

Restart=always

[Install]
WantedBy=multi-user.target

That doesn't work. I was starting to think the problem was Ruby not being installed for all users, so I've installed RVM for all users and still get the same problem. My server has only root and my-user.

Looking at how Capistrano deploys, the command it runs is: cd /home/my-user/apps/MyApp/current && ( RACK_ENV=production /home/my-user/.rvm/bin/rvm default do bundle exec puma -C /home/my-user/apps/MyApp/shared/puma.rb --daemon ) . If I use the aforementioned command, I get an error from Systmd complaining about missing parameters. So I've written a script with it and got the service file to call this script to start the app.

That doesn't work either. Note that if I call the script from anywhere on the server the script does start the App, so its an issue on configuring Systemd, but I can't figure out what's wrong and I'm not sure how to debug it. I've seen the debug page on System's website, but it didn't help me. If I run systemctl status puma.service all it tells me is that the service is in failed state, but it doesn't tell me how or why.

Also worth noting: If I run bundle exec puma -C /home/my-user/apps/MyApp/shared/puma.rb from my App folder it works ok, so how I could duplicate this command with Systemd service?

At the end the problem was twofold: 1) rvm wasn't installed properly for all users, which meant the deployer user didn't have ruby/bundle/etc available and secondarily the script was also wrong. For reference below is the revised script that worked for me:

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

[Service]
Type=simple

User=deployer

WorkingDirectory=/var/www/apps/MRCbe/current

ExecStart=/bin/bash -lc 'bundle exec puma -C /var/www/apps/MRCbe/shared/puma.rb'

Restart=always

[Install]
WantedBy=multi-user.target

Have you looked into Foreman ? Foreman makes it easy to start and stop your application if it has multiple processes. Incidentally it also provides an export function that can generate some systemd or upstart scripts for you to (re)start and stop your application.

As you are already using capistrano you can use capistrano-foreman to integrate all this nicely with capistrano.

I hope you find some use in these resources

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM