Table of Contents
- Understanding Systemd User Sessions
- 1.1 What is a User Session?
- 1.2 The User Manager:
systemd --user - 1.3 Session Types and Lifecycle
- User Services vs. System Services
- 2.1 Key Differences
- 2.2 Use Cases for Each
- Managing User Services: A Step-by-Step Guide
- 3.1 Creating a User Service File
- 3.2 Enabling, Starting, and Stopping Services
- 3.3 Checking Status and Logs
- Advanced Configuration: Dependencies, Environment, and Timers
- 4.1 Service Dependencies
- 4.2 Environment Variables
- 4.3 User Timers (Cron Alternatives)
- Troubleshooting User Services
- 5.1 Common Issues and Fixes
- 5.2 Lingering: Services Beyond Logout
- Best Practices for User Services
- Conclusion
- References
1. Understanding Systemd User Sessions
1.1 What is a User Session?
A user session in systemd is a context in which a user interacts with the system, starting when the user logs in (via GUI, terminal, or SSH) and ending when they log out. Systemd uses logind (a component of systemd) to manage user sessions, tracking login state, seat information (e.g., physical vs. remote), and session types.
User sessions are critical because they isolate user-specific processes from system-wide ones, ensuring security and resource separation. For example, a desktop user’s session includes their window manager, terminal, and background apps, all running with their user ID (UID).
1.2 The User Manager: systemd --user
Each user session spawns a user manager (systemd --user), a lightweight systemd instance that manages user-specific services. Unlike the system manager (systemd), which runs as root and manages system services, the user manager runs as the logged-in user and handles services defined in the user’s context.
You can interact with the user manager via systemctl --user (instead of the regular systemctl for system services). The user manager persists only for the duration of the user’s session—unless configured to “linger” (see Section 5.2).
1.3 Session Types and Lifecycle
Systemd categorizes user sessions by type, which determines which services start automatically:
- Graphical Session: Started via a display manager (e.g., GDM, LightDM). Triggers services dependent on
graphical-session.target(e.g., desktop notifications, screen savers). - Terminal Session: Started via
getty(local terminal) orsshd(remote SSH). Triggers services dependent onmulti-user.target. - Idle Session: A session with no active user input (e.g., after locking the screen). Some services (e.g., power-saving tools) may activate here.
Sessions start when a user logs in and end on logout. The user manager stops all user services when the session ends, unless lingering is enabled.
2. User Services vs. System Services
| Feature | User Services | System Services |
|---|---|---|
| Managed by | systemctl --user | systemctl (root) |
| Runs as | Logged-in user (non-root) | Root (or specified user via User= in .service) |
| Service File Paths | ~/.config/systemd/user/ (user-specific)/usr/lib/systemd/user/ (distro-provided) | /etc/systemd/system/ (admin-defined)/usr/lib/systemd/system/ (distro-provided) |
| Lifecycle | Tied to user session (unless lingering) | Persists across reboots (unless transient) |
| Use Cases | Personal scripts, background apps (e.g., Syncthing, Redshift), user cron jobs | System daemons (e.g., sshd, nginx), hardware management (e.g., bluetooth.service) |
2.1 Key Takeaway
Use user services for tasks specific to your user account (e.g., syncing files, launching a custom script on login). Use system services for tasks requiring root access or system-wide scope (e.g., network services, device drivers).
3. Managing User Services: A Step-by-Step Guide
3.1 Creating a User Service File
User service files follow the same .service format as system services but are stored in user-specific directories. Let’s create a simple service to run a backup script on login.
Example Service File: backup.service
Create ~/.config/systemd/user/backup.service with:
[Unit]
Description=Daily User Backup Script
Documentation=file:///home/user/docs/backup.md
After=network.target # Start after network is available
[Service]
Type=oneshot # Runs once and exits (use "simple" for long-running daemons)
ExecStart=/home/user/scripts/backup.sh # Path to your script
Restart=no # Don’t restart after exit (use "on-failure" for daemons)
[Install]
WantedBy=default.target # Start when user session starts
- [Unit]: Metadata (description, dependencies).
After=network.targetensures the script runs after the network is up. - [Service]: Execution details.
Type=oneshotis for one-time tasks; useType=simplefor long-running processes (e.g.,syncthing). - [Install]: Defines when the service starts.
WantedBy=default.targetlinks it to the user session’s default target (equivalent tomulti-user.targetfor users).
3.2 Enabling, Starting, and Stopping Services
Once the service file is created, use systemctl --user to manage it:
| Action | Command |
|---|---|
Reload user manager (after editing .service files) | systemctl --user daemon-reload |
| Enable service (start on session login) | systemctl --user enable backup.service |
| Start service immediately | systemctl --user start backup.service |
| Check service status | systemctl --user status backup.service |
| Stop service (if running) | systemctl --user stop backup.service |
| Disable service (stop auto-start) | systemctl --user disable backup.service |
3.3 Checking Status and Logs
- Status:
systemctl --user status backup.serviceshows runtime info (PID, exit code, recent logs). - Logs: User service logs are stored in the journal. View them with:
journalctl --user -u backup.service # Logs for "backup.service" journalctl --user --since "10 minutes ago" # Recent user logs
4. Advanced Configuration: Dependencies, Environment, and Timers
4.1 Service Dependencies
Control service order with [Unit] section directives:
After=network.target: Start afternetwork.targetis active.Requires=dbus.service: Fail ifdbus.serviceisn’t available (strict dependency).Wants=syncthing.service: Startsyncthing.serviceif possible (weak dependency).
Example: Start a service only after the graphical session loads:
[Unit]
After=graphical-session.target
Wants=graphical-session.target
4.2 Environment Variables
Inject environment variables into your service with Environment= or EnvironmentFile=:
Example: Set a BACKUP_DIR variable
[Service]
Environment="BACKUP_DIR=/home/user/backups"
ExecStart=/home/user/scripts/backup.sh "$BACKUP_DIR"
For sensitive data (e.g., API keys), use an environment file:
[Service]
EnvironmentFile=/home/user/.config/backup.env # File with "API_KEY=secret"
4.3 User Timers (Cron Alternatives)
Systemd timers replace cron for scheduling user tasks. They’re more flexible (support calendar events, dependencies) and integrate with the user manager.
Example: Daily Backup Timer
-
Create
~/.config/systemd/user/backup.timer:[Unit] Description=Run backup script daily at 2 AM [Timer] OnCalendar=*-*-* 02:00:00 # Daily at 2 AM Persistent=true # Run missed jobs on startup Unit=backup.service # Service to trigger [Install] WantedBy=timers.target -
Enable and start the timer:
systemctl --user enable --now backup.timer -
List active timers:
systemctl --user list-timers
5. Troubleshooting User Services
5.1 Common Issues and Fixes
| Issue | Fix |
|---|---|
| Service fails to start | Check systemctl --user status backup.service for errors. Verify ExecStart path and permissions. |
| Service doesn’t start on login | Ensure WantedBy=default.target is set in [Install], and the service is enabled with systemctl --user enable. |
| Logs missing | Use journalctl --user -u backup.service --no-pager to view logs. |
| Service stops after logout | Enable lingering (see 5.2) to keep services running post-logout. |
5.2 Lingering: Services Beyond Logout
By default, the user manager stops when the user logs out. To keep user services running 24/7 (e.g., a personal server), enable lingering with loginctl:
loginctl enable-linger $USER # Keep user manager running after logout
loginctl disable-linger $USER # Revert (stop services on logout)
Lingering is ideal for headless setups (e.g., a Raspberry Pi running user services like transmission-daemon).
6. Best Practices for User Services
- Keep Services Simple: Split complex tasks into smaller services with clear dependencies.
- Use
Type=oneshotfor Scripts: For one-time tasks (e.g., backups),Type=oneshotensures the service exits cleanly. - Avoid Root Dependencies: User services run as your UID—don’t hardcode paths like
/root/or require sudo. - Document Services: Add
Documentation=in[Unit]to link to notes (e.g.,Documentation=file:///home/user/docs/backup.md). - Version Control Service Files: Store
~/.config/systemd/user/in Git to sync across machines.
7. Conclusion
Systemd user sessions and services empower users to automate tasks, manage background apps, and customize their environment without root access. By leveraging systemctl --user, user timers, and lingering, you can build a robust, personalized workflow tailored to your needs.
Whether you’re a developer automating scripts or a desktop user managing background tools, mastering user services unlocks systemd’s full potential.