To create and manage user login services on Linux Mint 21.2, you must place unit files in the ~/.config/systemd/user/ directory and enable them using the --user flag. This approach ensures that your custom scripts or applications start automatically when you log into your graphical session without requiring root privileges.
Understanding User Services vs System Services
Systemd manages two distinct types of services: system-level and user-level. System services run as root and start during the boot process before any user logs in. In contrast, user services are tied to a specific user session. They start when you authenticate and stop when you log out. This distinction is critical for desktop environments like Cinnamon, MATE, or Xfce found in Linux Mint, where you often need background tasks to persist only while you are active. Attempting to manage these services with standard system commands will fail because they operate in different contexts. You cannot simply usesystemctl enable myservice for a user task. Instead, you must target the user instance of systemd. This separation provides better security and resource management, preventing a single user's service from interfering with system-wide operations.
Creating the Service Unit File
The first step is to create the directory structure for user-specific units. Open your terminal and execute the following command to ensure the necessary folder exists:mkdir -p ~/.config/systemd/user
Next, create a new file within this directory. For example, if you want to run a script located at /home/user/scripts/myscript.sh, you would create a file named myscript.service. The content of this file defines how systemd should handle your application. A basic template looks like this:
[Unit]
Description=My Custom User Script
After=default.target
[Service]
Type=simple
ExecStart=/home/user/scripts/myscript.sh
Restart=on-failure
[Install]
WantedBy=default.target
Several directives here are important. Type=simple indicates that the process started by ExecStart is the main process. Restart=on-failure tells systemd to restart the service if it exits with a non-zero status code. Note that some users look for options like KeepAlive, but this is not a valid directive in modern systemd unit files. Use RestartPolicy or the Restart field instead to control behavior after crashes.
For more complex timing needs, you might explore articles on controlling execution timing in service files to add delays or conditions before startup.
Enabling and Starting the Service
Once the unit file is saved, you need to reload the systemd daemon so it recognizes the new configuration. Because this is a user service, you must use the--user flag. Run the following command to reload the configuration:
systemctl --user daemon-reload
Now, you can enable the service to ensure it starts automatically upon login. Enabling creates symbolic links in the appropriate directories so systemd knows to launch this service when the user session begins.
systemctl --user enable myscript.service
To start the service immediately without waiting for a logout/login cycle, use:
systemctl --user start myscript.service
You can verify the status using:
systemctl --user status myscript.service
This command provides real-time feedback on whether the service is running, along with recent log entries. If the service fails to start, check the journal output for errors related to permissions or missing executables.
Managing Persistence and Reboots
A common concern is ensuring the service survives reboots. Since Linux Mint uses systemd, enabling the service viasystemctl --user enable handles this automatically. However, unlike system services, user services do not start until a user logs in. If you need a service to run even when no one is logged in, you must use a system-level service instead.
If you encounter issues where the service stops unexpectedly, review the Restart settings. Sometimes, aggressive restart policies can lead to loops. For insights on why a service might not restart after being killed, refer to guides on systemd restarting behavior. Additionally, be aware that shutting down the system requires careful ordering of service closures to prevent data loss, which is covered in resources about preserving order of closing services.
Troubleshooting Common Issues
When managing user services, several pitfalls can arise. First, ensure your script has executable permissions. You can set this usingchmod +x /path/to/script.sh. Second, check the environment variables. User services inherit the environment of the login session, but sometimes paths differ. Using absolute paths in ExecStart is highly recommended over relative ones.
Third, if your service seems to hang or timeout, check the TimeoutStopSec parameter. By default, systemd waits for a certain period before forcing a kill. Adjusting this can help with graceful shutdowns. For those dealing with web-based tools like code-server, similar principles apply, though network binding may introduce additional complexity regarding blank pages or connection drops.
Finally, always monitor the journal logs. The command journalctl --user -u myscript.service -f follows the logs in real-time. This is invaluable for debugging silent failures where the service appears enabled but does nothing.
Frequently Asked Questions
Why doesn't my user service start after a reboot?
User services only start when a user logs into the system, not at the boot screen. Ensure you have successfully enabled the service withsystemctl --user enable and that you are logging into the correct user account.
Can I use environment variables in my service file?
Yes, you can define variables using theEnvironment directive in the [Service] section. However, it is often cleaner to source a profile script in your ExecStart command if many variables are needed.
How do I view the logs for a specific user service?
Use thejournalctl command with the --user flag and the -u option followed by the service name. This filters the system journal to show only entries generated by that specific user unit.
What happens if my script crashes repeatedly?
If you have configuredRestart=on-failure, systemd will attempt to restart the service. It employs an exponential backoff delay between restart attempts to prevent overwhelming the system, eventually giving up if the failure persists too long.