Environment="USER=ubuntu" "Path=/home/ubuntu/console/bin"
WorkingDirectory=/home/ubuntu/console/bin
ExecStart=/bin/sh -ec "exec /sbin/start-stop-daemon -S -c ${USER} -d ${Path} --pidfile=/var/run/console.pid --oknodo --exec consoleExecutable " #2>/dev/null
ExecStop=/bin/sh -ec "exec /sbin/start-stop-daemon -K --quiet -c ${USER} -d ${Path} --pidfile=/var/run/console.pid --retry=TERM/30/KILL/5 --oknodo --exec consoleExecutable" #2>/dev/null
This is almost worthy of the systemd House of Horror. Were it not the case that there's a horror story already in there that does this.
Do not use start-stop-daemon
in a service unit to do all of the things that a service unit already does. With unnecessary PID files and the wrongheaded assumption that ExecStart
accepts shell syntax comments, no less.
And do not do what the other answer says and try to bodge it with Type=forking
. That makes things worse, not better.
The nonsense with start-stop-daemon
is why things are going wrong. Because the process running start-stop-daemon
does not become the service, but in fact exits pretty much imediately, systemd is thinking that your service is terminating. In your first systemctl status
output, you can see that systemd is in the middle of sending SIGTERM
to clean up all left-over running processes after running the ExecStop
action, which is what it does when it thinks that a service has terminated.
Just do things simply:
Type=simple
WorkingDirectory=/home/ubuntu/console/bin
User=ubuntu
ExecStart=/home/ubuntu/console/bin/consoleExecutable
No ExecStop
nor Environment
is actually required.
Further reading
I was able to accomplish this via the following unit file:
[Unit]
Description=User Graphical Login
Requires=default.target
After=default.target
I will then manually start the target as it has no Install
section and will not get started on its own.
systemctl --user start user-graphical-login.target
Best Answer
1.)
multi-user.target
is basically the closest equivalent of classic SysVinit runlevel 3 thatsystemd
has. When asystemd
system boots up,systemd
is trying to make the system state match the state specified bydefault.target
- which is usually an alias for eithergraphical.target
ormulti-user.target
.multi-user.target
normally defines a system state where all network services are started up and the system will accept logins, but a local GUI is not started. This is the typical default system state for server systems, which might be rack-mounted headless systems in a remote server room.graphical.target
is another possible alias fordefault.target
. Normally it's defined as a superset of themulti-user.target
: it includes everything themulti-user.target
does, plus the activation of a local GUI login. So kind of like runlevel 5 in classic SysVinit.The line
WantedBy=multi-user.target
in a service is essentially the same as specifying "this service should start in runlevels 3, 4 and 5" in SysVinit systems: it tellssystemd
that this service should be started as part of normal system start-up, whether or not a local GUI is active.However,
WantedBy
is separate from the enabled/disabled state: so in another sense, it's sort of a "preset": it determines under what conditions the automatic start may happen, but only when the service is enabled in the first place.2.) if you omit the
WantedBy=multi-user.target
line and no other enabled service includes aRequires=your.service
orWants=your.service
in its service definition, your service will not be started automatically.systemd
works on dependencies, and at boot time, if nothingRequires
orWants
your service, it won't be started even if the service is enabled.Sure, you could edit your
default.target
to add or deleteRequires
orWants
lines for any services you want started at boot time - but so that you can just drop a new service file into the system and have it work by default (which makes things very easy for software package managers),systemd
has theWantedBy
andRequiredBy
keywords which can be used to insertWants
andRequires
-type dependencies (respectively) from "the other end".3.) You should omit the line if you don't want the service to be ever started automatically at boot time, or this service is a part of a chain of dependencies you've defined explicitly.
For example, you might be refactoring server application A and for some reason or another decide to split some optional functionality off it into a separate service B, to allow the user the choice of not installing it if it isn't needed. You could then make service B a separate
service-B.rpm
, and defineB.service
withWantedBy=A.service
to makesystemd
start up service B automatically whenever service A is started - but only whenservice-B.rpm
is actually installed.Note that a
Wants
orWantedBy
only says that the system should startup one service whenever another service or target is also started, but it specifies nothing at all about the startup/shutdown order. If you need service B to be already running when service A starts up, you'd need to addBefore=A.service
in theB.service
file to explicitly specify the start-up order dependency.4.) Anytime you do want the service to have the capability of being started automatically at boot time, and there are no other dependencies already defined.