🎁 New User? Get 20% off your first purchase with code NEWUSER20 Register Now →
Menu

Categories

Systemd Service Files: Creating and Managing Custom Linux Services

Systemd Service Files: Creating and Managing Custom Linux Services

Systemd is the init system and service manager used by most modern Linux distributions. Understanding how to create and manage custom service files gives you full control over how your applications start, stop, restart, and recover from failures.

Basic Service File Structure

# /etc/systemd/system/myapp.service
[Unit]
Description=My Application Server
Documentation=https://docs.myapp.com
After=network.target postgresql.service
Wants=postgresql.service

[Service]
Type=simple
User=appuser
Group=appgroup
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/server --config /etc/myapp/config.yml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Service Types

  • simple: The default. The process started by ExecStart is the main process.
  • forking: The process forks and the parent exits. Use for traditional daemons.
  • oneshot: Process exits after completing its task. Good for scripts.
  • notify: Like simple, but the process signals readiness via sd_notify.
  • idle: Like simple, but execution is delayed until all jobs are dispatched.

Restart Policies

[Service]
# Restart options
Restart=always              # Always restart
Restart=on-failure          # Restart only on non-zero exit
Restart=on-abnormal         # Restart on signal, timeout, watchdog
Restart=on-abort            # Restart only on signal

RestartSec=5                # Wait 5 seconds before restart
StartLimitIntervalSec=300   # Rate limit: within 300 seconds...
StartLimitBurst=5           # ...allow max 5 restarts

Environment and Security

[Service]
# Environment variables
Environment=NODE_ENV=production
Environment=PORT=3000
EnvironmentFile=/etc/myapp/env

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/myapp /var/log/myapp
PrivateTmp=true
CapabilityBoundingSet=CAP_NET_BIND_SERVICE

Managing Services

# Reload systemd after editing service files
sudo systemctl daemon-reload

# Start/Stop/Restart
sudo systemctl start myapp
sudo systemctl stop myapp
sudo systemctl restart myapp

# Enable at boot
sudo systemctl enable myapp

# Check status and logs
systemctl status myapp
journalctl -u myapp -f
journalctl -u myapp --since "1 hour ago"

Practical Examples

Node.js Application

[Unit]
Description=Node.js API Server
After=network.target

[Service]
Type=simple
User=nodejs
WorkingDirectory=/opt/api
ExecStart=/usr/bin/node server.js
Environment=NODE_ENV=production
Environment=PORT=3000
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Python Application with Gunicorn

[Unit]
Description=Gunicorn WSGI Server
After=network.target

[Service]
Type=notify
User=www-data
WorkingDirectory=/opt/webapp
ExecStart=/opt/webapp/venv/bin/gunicorn --bind 0.0.0.0:8000 --workers 4 wsgi:app
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target

Systemd Timers (Cron Alternative)

# /etc/systemd/system/cleanup.timer
[Unit]
Description=Run cleanup daily

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
RandomizedDelaySec=600

[Install]
WantedBy=timers.target

# /etc/systemd/system/cleanup.service
[Unit]
Description=Log Cleanup Task

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup-logs.sh

Debugging Tips

  1. Always run systemctl daemon-reload after editing service files
  2. Check syntax with systemd-analyze verify myapp.service
  3. View full logs with journalctl -u myapp -e
  4. Check dependencies with systemctl list-dependencies myapp
  5. Use systemctl cat myapp to see the effective configuration

Systemd service files give you fine-grained control over your applications. Use the security options to harden your services and the restart policies to build resilient systems that recover automatically from failures.

Share this article:
Nico Brandt
About the Author

Nico Brandt

JavaScript Development, TypeScript Engineering, Web Application Architecture, Technical Documentation

Nico Brandt is a JavaScript and TypeScript developer focused on building well-structured, maintainable, and scalable web applications.

He works extensively with modern JavaScript and TypeScript across frontend and backend environments, emphasizing type safety, code readability, and predictable application behavior.

...
JavaScript TypeScript Frontend Development Backend APIs Asynchronous Programming

Stay Updated

Subscribe to our newsletter for the latest tutorials, tips, and exclusive offers.