Systemd Service Creation Guide

Complete tutorial for creating startup and shutdown scripts with systemd

Introduction to Systemd

Systemd is a system and service manager for Linux operating systems. It's the first process started during boot (PID 1) and manages all other processes and services.

Creating systemd services allows you to:

Note: This guide assumes you're working on a Linux system with systemd installed. Most modern distributions (Ubuntu 15.04+, Debian 8+, CentOS 7+, etc.) use systemd by default.

Understanding Systemd Service Files

Systemd services are defined using .service files, which are plain text configuration files with a specific structure.

Service File Locations

Basic Service File Structure

[Unit] Description=Service description After=network.target [Service] Type=simple ExecStart=/path/to/startup/script ExecStop=/path/to/shutdown/script User=username Group=groupname Restart=on-failure [Install] WantedBy=multi-user.target

Common [Unit] Section Directives

Directive Description
Description Human-readable description of the service
After Specifies services that should be started before this service
Before Specifies services that should be started after this service
Requires Other services that must be started for this service to run
Wants Other services that should be started but aren't required

Common [Service] Section Directives

Directive Description
Type Service type (simple, forking, oneshot, dbus, notify)
ExecStart Command to start the service
ExecStop Command to stop the service
ExecReload Command to reload the service
User User account to run the service as
Group Group to run the service as
WorkingDirectory Working directory for the service
Restart When to restart the service (no, on-success, on-failure, always)

Creating a Startup Script

A startup script initializes your application or service when the system boots or when the service is manually started.

1. Create the Script

Create a shell script that will start your application. Make sure it's executable.

#!/bin/bash # Example startup script for a web application echo "Starting MyWebApp at $(date)" >> /var/log/mywebapp.log # Change to application directory cd /opt/mywebapp # Start the application ./bin/mywebapp start # If the application runs in the foreground, you might need to use: # exec ./bin/mywebapp

2. Make the Script Executable

Set the proper permissions for your script:

chmod +x /path/to/your/startup-script.sh

3. Test the Script

Run the script manually to ensure it works correctly:

sudo /path/to/your/startup-script.sh

Important: For services that run in the foreground (Type=simple), the script should not exit until the service stops. For background services (Type=forking), the script should fork and then exit.

Creating a Shutdown Script

A shutdown script properly stops your application when the system shuts down or when the service is stopped.

1. Create the Script

Create a shell script that will gracefully stop your application.

#!/bin/bash # Example shutdown script for a web application echo "Stopping MyWebApp at $(date)" >> /var/log/mywebapp.log # Change to application directory cd /opt/mywebapp # Stop the application gracefully ./bin/mywebapp stop # If the application needs a force kill after a timeout: # timeout 30s ./bin/mywebapp stop # if [ $? -ne 0 ]; then # pkill -f mywebapp # fi

2. Make the Script Executable

Set the proper permissions:

chmod +x /path/to/your/shutdown-script.sh

3. Test the Script

Run the script manually to ensure it stops your application correctly:

sudo /path/to/your/shutdown-script.sh

Tip: Your shutdown script should handle both graceful shutdown and force termination if necessary. Always try to stop the application gracefully first, then use force methods if it doesn't respond within a reasonable time.

Complete Example: Web Application Service

Let's create a complete example for a hypothetical web application called "MyWebApp".

1. Create the Service File

Create the file at /etc/systemd/system/mywebapp.service:

[Unit] Description=MyWebApp Service After=network.target Wants=network.target [Service] Type=simple User=webapp Group=webapp WorkingDirectory=/opt/mywebapp ExecStart=/opt/mywebapp/scripts/start.sh ExecStop=/opt/mywebapp/scripts/stop.sh ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=5 TimeoutStopSec=30 # Security settings NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ReadWritePaths=/opt/mywebapp/logs /opt/mywebapp/data [Install] WantedBy=multi-user.target

2. Create the Startup Script

Create /opt/mywebapp/scripts/start.sh:

#!/bin/bash # MyWebApp Startup Script echo "$(date): Starting MyWebApp" >> /opt/mywebapp/logs/service.log # Check if required directories exist mkdir -p /opt/mywebapp/logs mkdir -p /opt/mywebapp/data # Start the application exec /opt/mywebapp/bin/mywebapp \ --config /opt/mywebapp/config/app.conf \ --logfile /opt/mywebapp/logs/app.log \ --pidfile /opt/mywebapp/data/app.pid

3. Create the Shutdown Script

Create /opt/mywebapp/scripts/stop.sh:

#!/bin/bash # MyWebApp Shutdown Script echo "$(date): Stopping MyWebApp" >> /opt/mywebapp/logs/service.log # Try graceful shutdown first if [ -f /opt/mywebapp/data/app.pid ]; then PID=$(cat /opt/mywebapp/data/app.pid) kill -TERM $PID # Wait for process to exit for i in {1..30}; do if ! kill -0 $PID 2>/dev/null; then echo "MyWebApp stopped gracefully" >> /opt/mywebapp/logs/service.log exit 0 fi sleep 1 done # Force kill if still running echo "MyWebApp did not stop gracefully, forcing kill" >> /opt/mywebapp/logs/service.log kill -KILL $PID fi # Fallback: kill by process name if PID file doesn't exist pkill -f "mywebapp"

4. Set Permissions

# Make scripts executable chmod +x /opt/mywebapp/scripts/start.sh chmod +x /opt/mywebapp/scripts/stop.sh # Create the webapp user and set ownership sudo useradd -r -s /bin/false webapp sudo chown -R webapp:webapp /opt/mywebapp

Managing Systemd Services

Once you've created your service file and scripts, you need to enable and manage the service.

Reload Systemd

After creating or modifying a service file, reload systemd to recognize the changes:

sudo systemctl daemon-reload

Enable the Service

Enable the service to start automatically at boot:

sudo systemctl enable mywebapp.service

Start the Service

Start the service immediately:

sudo systemctl start mywebapp.service

Check Service Status

Verify the service is running correctly:

sudo systemctl status mywebapp.service

Stop the Service

Stop the service:

sudo systemctl stop mywebapp.service

Restart the Service

Restart the service:

sudo systemctl restart mywebapp.service

View Service Logs

Check the service logs using journalctl:

sudo journalctl -u mywebapp.service -f

Disable the Service

Prevent the service from starting at boot:

sudo systemctl disable mywebapp.service

Success: You've now created a complete systemd service with proper startup and shutdown scripts! Your application will now start automatically on system boot and stop gracefully on system shutdown.