1. Structure of Service Unit Files
A complete service unit file consists of three main parts: <span>[Unit]</span>, <span>[Service]</span>, and <span>[Install]</span>. Below are the core functions and commonly used configuration items for each part:
1. <span>[Unit]</span> — Basic Properties and Dependencies
- • Description: A brief description of the service (required).
- • After: Defines which other services this service should start after (e.g.,
<span>network.target</span>). - • Requires: List of strong dependencies; if missing, the current service cannot start.
- • Wants: List of weak dependencies; indicates association but does not affect the startup order.
- • Documentation: Link to service documentation (optional).
[Unit]
Description=High Performance Web Server
After=network.target
Requires=network.target
2. <span>[Service]</span> — Definition of Service Behavior
| Configuration Item | Description | Example Value |
|---|---|---|
<span>Type</span> |
Service type– <span>simple</span> (default): The main process is the service itself– <span>forking</span>: Requires forking a child process– <span>oneshot</span>: One-time task– <span>notify</span>: Notifies readiness via <span>sd_notify</span> |
<span>forking</span> |
<span>ExecStart</span> |
Command or script path to start the service | <span>/usr/sbin/nginx</span> |
<span>ExecStop</span> |
Command to stop the service (optional) | <span>/usr/sbin/nginx -s quit</span> |
<span>Restart</span> |
Restart policy– <span>always</span>: Restart in any case– <span>on-failure</span>: Restart only on abnormal exit |
<span>on-failure</span> |
<span>User</span> |
User to run the service | <span>nginx</span> |
<span>Group</span> |
Group to run the service | <span>nginx</span> |
<span>WorkingDirectory</span> |
Working directory of the service | <span>/var/www/html</span> |
<span>Environment</span> |
Environment variable settings | <span>PATH=/usr/local/bin</span> |
3. <span>[Install]</span> — Installation and Startup Configuration
- • WantedBy: Specifies which target the service should bind to, determining the startup behavior. Common targets include
<span>multi-user.target</span>(multi-user mode) and<span>graphical.target</span>(graphical interface). - • Alias: Sets an alias for the service (optional).
[Install]
WantedBy=multi-user.target
2. Detailed Explanation of Key Configuration Items
1. Service Type (<span>Type</span>)
- • simple (default): Suitable for main processes that run directly (e.g., Java applications).
- • forking: Traditional Unix daemon mode, where the parent process forks a child process and exits (e.g., MySQL).
- • oneshot: Exits after executing a one-time task (e.g., backup scripts).
- • notify: The service must notify Systemd that it is ready via the
<span>sd_notify</span>interface (suitable for complex applications).
2. Restart Policy (<span>Restart</span>)
- •
<span>on-failure</span>: Restart only when the service exits abnormally (return code not 0). - •
<span>always</span>: Restart regardless of the exit reason (should avoid infinite loops). - •
<span>unless-stopped</span>: Always restart unless stopped manually.
3. User and Permissions (<span>User</span>/<span>Group</span>)
- • It is recommended to run services as a non-root user for security.
- • The running identity can be explicitly specified using
<span>User=</span>and<span>Group=</span>. - • If access to specific devices or files is required, it should be combined with
<span>DevicePolicy</span>or additional device permission rules.
3. Service Management Commands
| Command | Description |
|---|---|
| systemctl start prometheus | Start the service immediately |
| systemctl stop prometheus | Stop the service |
| systemctl restart prometheus | Restart the service |
| systemctl status prometheus | View service status and logs |
| systemctl enable prometheus | Enable service to start on boot |
| systemctl disable prometheus | Disable service from starting on boot |
| systemctl daemon-reload | Reload all modified configuration files |
| systemctl list-units –type=service | List all service units |
4. Practical Example: Custom Python Script Service
1. Create Service File
nano /etc/systemd/system/myapp.service
2. Write Configuration
[Unit]
Description=My Custom Python Application
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/myapp/app.py
WorkingDirectory=/opt/myapp
User=myuser
Group=mygroup
Restart=on-failure
[Install]
WantedBy=multi-user.target
3. Enable and Start Service
systemctl daemon-reload # Reload configuration
systemctl enable myapp # Enable on boot
systemctl start myapp # Start immediately
5. Common Issues Troubleshooting
| Issue | Possible Cause | Solution |
|---|---|---|
| Service cannot start | Incorrect command path or insufficient permissions | Check <span>ExecStart</span> path and user permissions |
| Service starts and then exits | Process does not correctly stay in the foreground | Try changing <span>Type=forking</span> |
| No output in logs | Standard output/error not redirected | Add <span>StandardOutput=journal</span> |
| Missing dependencies | After/Requires not correctly declared | Check dependencies and whether target units exist |
6. Advanced Techniques
1. Passing Environment Variables
[Service]
Environment="KEY=VALUE"
EnvironmentFile=-/etc/default/myapp.conf # Load environment variables from file
2. Resource Limits
[Service]
CPUAccounting=true
CPULimit=50% # CPU usage limit
MemoryLimit=1G # Memory limit
3. Timer Unit Integration for Scheduled Tasks
If you need to execute a service on a schedule, you can create a <span>.timer</span> unit:
[Unit]
Description=Daily Backup Job
[Timer]
OnCalendar=23:00 # Trigger at 23:00 every day
Persistent=true # Execute missed jobs
With the above configuration, Systemd can achieve fine-grained control over services, covering startup order, dependencies, resource limits, security policies, etc. It is recommended to verify the validity of the configuration using <span>systemctl status</span> and logs (<span>journalctl -u <service></span>) before actual deployment.