Why is systemd stopping service immediately after it is started?

Solution 1:

You didn't tell systemd what kind of daemon this is and what to expect from it (most importantly, it needs to how to know when the daemon has finally started).

The default is Type=simple, which means the first process is considered the main service process. The moment it starts, the entire service is considered "active (started)"; the moment it exits, the entire service gets stopped.

The other common mode is Type=forking, where the initial process is expected to fork at least once and exit, leaving a child running "in background" or "daemonized" as some call it.

But if you're going through a "whateverctl" tool, you're always going to see the behavior that needs Type=forking, since the tool itself will try to start the daemon "in background" and exit itself.

Solution 2:

None of the above and similar SO answers worked for me. But this post eventually did.

[Unit]
Description=Setup foo
#After=network.target

[Service]
Type=oneshot
ExecStart=/opt/foo/setup-foo.sh
RemainAfterExit=true
ExecStop=/opt/foo/teardown-foo.sh
StandardOutput=journal

[Install]
WantedBy=multi-user.target

What did the trick was the RemainAfterExit=true directive. That's because my script didn't leave any trace of itself for systemd to look at, so next systemd step was always to call ExecStop to stop "this strange script that doesn't leave a daemon behind". Moot but true.

UPDATE 20180316: Ok, I totally forgot everything about systemd services in these few months, so I was re-doing all the work from scratch. Fortunately I vaguely remembered about this answer, passed half an hour looking for it and now I'm here again.

I'll try to add just a couple of things I've re-learned this time: systemd scripts must not be placed in /etc/init, they stay in the more hideous /etc/systemd/system directory, and they're called .service, not .conf!

After the script is in the correct directory, a sudo systemctl daemon-reload is desirable, but won't make the script name appear in sudo service [TAB] autocomplete list. Nevertheless, the new service can be launched with:

sudo service myservice start

And that's it, now the service is doing what has been written for. For sure the called script won't, but this is another problem.