Linux start service with user

systemd user services and systemctl —user

Most users are familiar with the system-wide systemd services managed by the systemctl command. But systemd services can be made for and entirely controlled by regular unprivileged users.

Regular services on Fedora and other systems with systemd as an init system, are usually found at /etc/systemd/system/ and managed with the root privileges. Think your packaged NGINX web server or the PostgreSQL database. We usually make our own, too, to run our long-running applications.

These services have one other thing in common. Once enabled, they start and stop with the system boot and shutdown:

$ sudo systemctl enable nginx.service 

That will be an essential distinction. Let’s see the other type of systemd service: one designed to be run by unprivileged users.

If we drop a systemd service in ~/.config/systemd/user , it will be picked up by systemd as a user service. The big advantage is that the particular user now manages this service without the need for sudo.

It does require the —user flag when invoking any of the systemctl commands:

$ systemctl --user enable myuser.service $ systemctl --user daemon-reload $ systemctl --user start myuser.service 

We can even use the global /etc/systemd/user/ location, making the service available to all users at once ( /usr/lib/systemd/user/ would be typically used by an RPM package on Fedora).

But what’s the real reason for having user services? To answer that, we have to realize when the enabled service starts and stops. If we enable a user service, it starts on user login, and runs as long as there is a session open for that user. Once the last session dies, the service stops.

That makes it perfect for all kinds of desktop software, and if you open /etc/systemd/user/ you might find there a lot of GNOME, Evolution, and other desktop services.

Читайте также:  Linux background python script

But what if we want to run a long-running service under an unprivileged user, like a web application service that persists across restarts? For this use-case, we have a User= directive that we can use in system services:

$ cat /etc/systemd/system/sharing.service [Unit] Description=Admin's Sharing Server [Service] Type=simple User=admin WorkingDirectory=/home/admin/shared ExecStart=/usr/bin/python3 -m http.server 8080 Restart=always [Install] WantedBy=multi-user.target 

If the above sharing service runs only when the admin is logged in, it would be quite limiting. So it’s a system service with the User directive within [Service] section. But it feels wrong not giving the admin an option to cancel this service.

To this end, we have to workaround it by enabling this in a sudoers file:

START="/bin/systemctl start sharing.service" STOP="/bin/systemctl stop sharing.service" ENABLE="/bin/systemctl enable sharing.service" DISABLE="/bin/systemctl disable sharing.service" echo 'admin ALL=(ALL) NOPASSWD: $START, $STOP, $ENABLE, $DISABLE' | tee /etc/sudoers.d/admin chmod 0440 /etc/sudoers.d/admin 

← 950+ copies sold!

Learn the ins and outs of web application deployment with Ruby, Python, and Linux.

← New new new

Save 100+ hours and forget international tax on your next Ruby on Rails business idea.

Источник

Bash init — start service under specific user

I am trying to create an init script in bash (Ubuntu) that starts a service under a specific user. Is there a better way to do that other than this?

4 Answers 4

Ubuntu uses start-stop-daemon which already supports this feature.

Use the skeleton file from /etc/init.d:

sudo cp /etc/init.d/skeleton /etc/init.d/mynewservice

Edit mynewservice appropriately.

Add the following parameter to the lines that call start-stop-daemon:

start-stop-daemon —start —quiet —pidfile $PIDFILE —exec $DAEMON —test > /dev/null \

start-stop-daemon —start —quiet —chuid someuser:somegroup —pidfile $PIDFILE —exec $DAEMON —test > /dev/null \

Finally, register your service and start it:

update-rc.d mynewservice defaults 99 && service mynewservice start

More info about other options for start-stop-daemon here

Alternatively, you can use the daemon function defined in your /etc/init.d/functions file:

If you look into its syntax you can do other things like defining PID file location, setting nice level, and whatnot. It’s otherwise really useful for starting up services as daemons. Services started up with daemon can easily be terminated by another functions function, killproc .

Читайте также:  Можно ли linux поставить поверх windows

Thanks. The problem I’m running into is that it’s a process that needs to be run from a particular directory but the process itself isn’t actually in that directory.

You can create a script under /etc/init.d/ say your_service_name, with minimal contents

Provide appropriate permission to the script. Now use update-rc.d command in the required /etc/rc.d directory to create a soft link for your script so that the script is run when system starts with the mentioned run level.
Please refer scripts under /etc/init.d/ for reference & please go through /etc/init.d/README for more details regarding writing the script. Man page for update-rc.d will also help to find out about the usage of update-rc.d . This definitely works on Ubuntu machine I use, but I’m guessing that this facility will be available across distros.
Hope this helps!

Источник

Managing services for non-root users with systemd

Systemd is mainly used to manage services on modern linux distributions, but it also allows non-root users to manage services running under their own account. This makes systemd a great alternative to services like supervisord as it is able to detect crashes and automatically restarts the service.

Configuring a user unit

The directory structure that holds unit files is similar to the systemwide configuration, but is located in a user’s home directory:

$ mkdir -p ~/.config/systemd/user 

In the user folder we can create service units with a .service extension. A unit is a ini-style file describing a service that has to be managed.

Let’s say we have a Laravel PHP queue worker that we want to be managed by systemd, called worker.service :

[Unit] Description=Laravel PHP queue worker [Service] ExecStart=/usr/bin/env php /path/to/my/project/artisan queue:work --sleep=3 --tries=3 [Install] WantedBy=default.target 

Run $ systemctl —user daemon-reload to make systemd recognize your changes.

Читайте также:  Ivms 4200 linux install

We can now manage this service with systemd:

  • $ systemctl —user start worker starts the service
  • $ systemctl —user stop worker stops the service
  • $ systemctl —user restart worker restarts the workers
  • $ systemctl —user status worker shows us the service status

If we want this service to start automatically when our user logs in, we have to enable it:

Viewing logs

Everything our PHP script writes to stdout and stderr will be recorded by journald. We can view the logs for this specific service:

On older versions of systemd (like the one shipped with Debian Jessie), you might need to use a flag specific to user units:

$ journalctl --user-unit worker 

Automatically restarting on failure

Let’s be honest: things go wrong. When our worker crashes we want to make sure it’s started again. Fortunately, we can configure systemd to restart on failure:

Add the following to the [Service] section of the unit file:

RestartSec=10s Restart=on-failure 

This makes systemd restart the service 10 seconds after it has stopped with a non-zero exit code. If the process exited cleanly, systemd considers the work as done and won’t restart the service until you manually start it later.

Starting user services at boot

By default, systemd starts enabled user units when the user logs in, and stops them once the user has logged out. This is great for desktop pcs where a user wants to run things while he’s using the computer. On servers, however, we may want to run those units all the time.

# loginctl enable-linger USERNAME 

You can check the status for each user by:

# loginctl user-status USERNAME 

It should show that the user is lingering:

vic (1000) Since: Fri 2017-09-01 21:54:29 CEST; 3s ago State: lingering Unit: user-1000.slice 

When the user is not logged in and does not have lingering enabled, loginctl doesn’t know about any user sessions so it will return an error:

Failed to get user: No user 1000 known or logged in 

Источник

Оцените статью
Adblock
detector