Introduction / Why This Matters
Systemd has become the standard for initialization and service management in most modern Linux distributions (Ubuntu, Debian, CentOS, Fedora). Understanding service management is a key skill for system administrators and developers working with servers. After completing this guide, you will be able to confidently start, stop, configure autostart, and diagnose issues with any service, as well as create your own.
Prerequisites / Preparation
- Terminal access with sudo privileges (or root).
- A Linux distribution that uses systemd (check with
systemctl --version). - Basic command-line knowledge.
Step 1: Checking for systemd and Listing Units
Let's confirm the system uses systemd and see which services (units) are available.
# Check systemd version
systemctl --version
# Show all loaded units (services, timers, sockets, etc.)
systemctl list-units --type=service --state=running
# Show ALL available units, including inactive ones
systemctl list-unit-files --type=service | head -20
Key unit statuses: loaded (unit file found), active (running), inactive (stopped), failed (failed with an error).
Step 2: Basic State Management Operations
Here are the essential commands for daily control.
# Start a service immediately (not permanently)
sudo systemctl start nginx
# Stop a service
sudo systemctl stop nginx
# Restart (stop and start again)
sudo systemctl restart nginx
# Reload (send SIGHUP, if the service supports it)
sudo systemctl reload nginx
# Check status (the most informative command)
sudo systemctl status nginx
In the status output, look at the Active: line and the recent logs in the journal section. If the status is failed (Result: exit-code), check the logs in the next step.
💡 Tip: For a quick restart with state cleanup, use
sudo systemctl try-restart nginx— it won't start the service if it's already stopped.
Step 3: Configuring Autostart (Enable/Disable)
Autostart is managed via symbolic links in the /etc/systemd/system/ directory.
# Enable autostart on next system boot
sudo systemctl enable nginx
# Creates a link: /etc/systemd/system/multi-user.target.wants/nginx.service -> /lib/systemd/system/nginx.service
# Disable autostart (removes the link, the service file remains)
sudo systemctl disable nginx
# Check if a service is enabled for autostart
systemctl is-enabled nginx
# Output: enabled, disabled, static, masked
⚠️ Important: The
enablecommand does not start the service immediately. For a one-time start, usestart; to start and enable autostart, useenable --now.
Step 4: Diagnostics with journalctl
Systemd logs are stored in a binary journal, accessible via journalctl.
# Show logs for ALL services in real-time (like tail -f)
sudo journalctl -f
# Show logs for a SPECIFIC service
sudo journalctl -u nginx.service
# Show logs since the last system boot (-b)
sudo journalctl -u nginx.service -b
# Filter by time (e.g., last 10 minutes)
sudo journalctl -u nginx.service --since "10 min ago"
# Show only error-level messages (error, crit, alert, emerg)
sudo journalctl -u nginx.service -p err
# Vacuum the journal (caution! requires disk space)
sudo journalctl --vacuum-time=3d # Keep logs only for the last 3 days
To search for text in logs, use standard grep:
sudo journalctl -u nginx.service | grep -i "permission"
Step 5: Creating a Simple Custom Service
Suppose you need to run the script /opt/myscript.sh at system startup.
- Create the service file
/etc/systemd/system/myscript.service:[Unit] Description=My Custom Script After=network.target [Service] Type=simple ExecStart=/opt/myscript.sh Restart=on-failure RestartSec=10 User=ubuntu Group=ubuntu [Install] WantedBy=multi-user.targetAfter— run after the network stack.Type=simple— the process runs in the foreground.Restart=on-failure— restart if it crashes.User/Group— which user to run as.WantedBy— which target unit (.target) this belongs to.
- Save the file and run:
# Reload systemd configuration (mandatory after creating/modifying files!) sudo systemctl daemon-reload # Enable and start immediately sudo systemctl enable --now myscript.service # Check status sudo systemctl status myscript.service
Verification
- Service status:
systemctl status <service>should showactive (running). - Autostart:
systemctl is-enabled <service>should returnenabled. - Logs:
journalctl -u <service> -n 20should show the last 20 log lines without errors. - Functionality: If it's a web server (nginx/apache), check the response with
curl http://localhost. If it's a background process, ensure it's running (ps aux | grep <process>).
Common Issues
| Problem / Symptom | Likely Cause | Solution |
|---|---|---|
Failed to start <service>. Unit <service> not found. | Incorrect service name or missing .service file. | Check the exact name with systemctl list-unit-files | grep <part_of_name>. Ensure the file is in /etc/systemd/system/ or /lib/systemd/system/. |
Permission denied or Access denied during start/stop | Running without sudo or insufficient permissions in the service file. | Use sudo. Check service file permissions: ls -l /etc/systemd/system/<service>.service. |
Service starts but immediately crashes (active (exited) or failed). | Error in ExecStart command, missing dependencies, permissions on script/binary. | Check logs: sudo journalctl -u <service> -b. Ensure the script is executable (chmod +x) and uses an absolute path. |
Failed to execute command: Permission denied (in journalctl logs) | The user specified in User= lacks permissions for required files/ports. | Fix file/directory permissions (chown, chmod) or run as root (not recommended). |
Changes to the service file don't apply after systemctl restart. | Forgot to run systemctl daemon-reload after editing the file. | Always run sudo systemctl daemon-reload after modifying .service files. |
masked status (service is blocked). | Someone ran systemctl mask. | Unmask it: sudo systemctl unmask <service>, then sudo systemctl enable <service>. |