Skip to content

Instantly share code, notes, and snippets.

@zealfire
Created April 28, 2018 15:42
Show Gist options
  • Save zealfire/6bdedb5f5adfb31bc3a271b15e5353f0 to your computer and use it in GitHub Desktop.
Save zealfire/6bdedb5f5adfb31bc3a271b15e5353f0 to your computer and use it in GitHub Desktop.

Systemd Example for a Simple Ruby Daemon Supervision | COMMENTS Since the new ubuntu versions migrated from upstart to systemd in order to unify basic Linux service behaviors across all distributions we now have to deal with systemd as a default service manager/supervisor. In this article I will describe basics of how to write your first service on this platform.

Services directory location:

1 /lib/systemd/system/*.service Logs location:

1 /var/log/syslog It’s even more convinient to fetch them with a special journalctl utility which reads a systemd journal:

1 $ journalctl --since "2017-02-25 00:00:00" Now let’s create a simple Ruby script which will run an infinite loop:

1 2 $ cd /home/username/ $ vim mydaemon.rb 1 2 3 4 5 6 $stdout.reopen('/home/username/mydaemon.log', 'a') $stdout.sync = true loop.with_index do |_, i| puts i sleep(3) end And start it as a daemon:

1 2 $ ruby mydaemon.rb & [1] pid Checking logs to make sure the daemon is running as expected:

1 2 3 4 5 6 $ tail -f mydaemon.log 0 1 2 3 ^C And stop it:

1 $ kill pid It’s time to add a systemd service which will start this daemon automatically and restart it whenever it was stopped or crashed.

1 2 3 4 5 6 7 8 9 10 11 $ vim /lib/systemd/system/mydaemon.service

[Unit] Description=Simple supervisor

[Service] User=username Group=username WorkingDirectory=/home/username Restart=always ExecStart=/usr/bin/ruby mydaemon.rb In contrary to upstart systemd does not start new services automatically. You can check it’s status with:

1 2 3 4 $ systemctl status mydaemon ● mydaemon.service - Simple supervisor Loaded: loaded (/lib/systemd/system/mydaemon.service; static; vendor preset: enabled) Active: inactive (dead) And start it with:

1 $ systemctl start mydaemon Now status should show mydaemon.rb was started and running with a pid assigned

1 2 3 4 5 6 7 8 9 10 $ systemctl status mydaemon ● mydaemon.service - Simple supervisor Loaded: loaded (/lib/systemd/system/mydaemon.service; static; vendor preset: enabled) Active: active (running) since date Main PID: pid (ruby) Tasks: 2 Memory: 4.0M CPU: 52ms CGroup: /system.slice/mydaemon.service └─pid /usr/bin/ruby mydaemon.rb If you now try to kill the process - supervisor should immediately restart it:

1 2 3 4 5 6 7 8 9 10 11 $ kill pid $ systemctl status mydaemon ● mydaemon.service - Simple supervisor Loaded: loaded (/lib/systemd/system/mydaemon.service; static; vendor preset: enabled) Active: active (running) since date Main PID: new_pid (ruby) Tasks: 2 Memory: 4.0M CPU: 49ms CGroup: /system.slice/mydaemon.service └─new_pid /usr/bin/ruby mydaemon.rb Helpful resources:

Systemd man Systemd for upstart users

Bigger systemd service example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [Unit] Description=My description here

After=another.target After=some.service

[Service] Type=simple # forking/oneshot/dbus/notify/idle

PIDFile=/absolute/file/name

User=username Group=groupname

WorkingDirectory=/home/username/some/dir

Restart=on-failure

Environment=ONE='one' "TWO='two two' too" THREE= EnvironmentFile=/path/to/file/with/variables

ExecStartPre=/run/some/command ExecStartPre=/run/some/other/command ExecStart=/usr/bin/node /opt/webhook/server.js ExecStartPost=/lastly/run/this

[Install] WantedBy=multi-user.target Restart options:

Upstart <-> Systemd commands cheatsheet:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment