Skip to content
Search RunEntLinux

Searches general documentation on RunEntLinux. Each distribution has its own documentation search.

    Browse this documentation

    Managing Service Units

    systemd service unit files define how to start, stop, and manage a background service. By mastering the structure and commonly used configuration options of unit files, you can create reliable system services for any application.

    systemd searches for unit files in the following directories, from highest to lowest priority:

    PathPurposePriority
    /etc/systemd/system/Administrator-customized unit filesHighest
    /run/systemd/system/Dynamically generated unit files at runtimeMedium
    /usr/lib/systemd/system/Unit files installed by packagesLowest

    Custom services should always be placed in the /etc/systemd/system/ directory.

    A standard service unit file consists of three main sections:

    Basic unit file structure
    [Unit]
    # Description and dependencies
    [Service]
    # Service runtime parameters
    [Install]
    # Installation (enable) behavior

    The [Unit] section provides description information and dependency relationships for the unit. It is a common configuration section shared by all unit types.

    Common [Unit] section options
    [Unit]
    Description=My Application Service
    Documentation=https://example.com/docs
    After=network.target
    Wants=network-online.target
    Requires=postgresql.service

    Common directives:

    DirectiveDescription
    Description=A short description of the service, displayed in systemctl status output
    Documentation=Documentation URL for reference
    After=Specifies startup ordering; this service starts after the specified units
    Before=Specifies startup ordering; this service starts before the specified units
    Requires=Hard dependency; this service cannot start if the specified units are not running
    Wants=Soft dependency; failure of the specified units does not affect this service
    BindsTo=Similar to Requires, but this service is also stopped when the specified unit stops

    The [Service] section is the core of a service unit file, defining the startup method, runtime parameters, and restart policies.

    Common [Service] section options
    [Service]
    Type=simple
    ExecStart=/usr/bin/myapp --config /etc/myapp/config.yml
    ExecReload=/bin/kill -HUP $MAINPID
    ExecStop=/bin/kill -SIGTERM $MAINPID
    Restart=on-failure
    RestartSec=5
    User=myapp
    Group=myapp
    WorkingDirectory=/opt/myapp
    Environment=NODE_ENV=production
    EnvironmentFile=/etc/myapp/env

    Type= specifies the startup method of the service and directly affects how systemd determines whether the service has started successfully:

    TypeDescriptionUse Case
    simple (default)The ExecStart process is the main processMost foreground applications
    forkingThe process forks and the parent exits; the child becomes the main processTraditional daemons (e.g., Apache)
    oneshotThe process runs to completion and exits; can be combined with RemainAfterExitInitialization scripts, one-time tasks
    notifyThe service proactively notifies systemd it is ready via sd_notify()Applications supporting sd_notify
    dbusThe service is considered started after acquiring a D-Bus nameD-Bus services
    idleSimilar to simple, but waits until other tasks are complete before startingConsole output-related services
    ValueDescription
    no (default)Do not restart automatically
    on-successRestart only on clean exit (exit code 0)
    on-failureRestart only on abnormal exit (recommended for daemons)
    on-abnormalRestart on signal termination or timeout
    on-abortRestart on uncaught signal
    alwaysRestart regardless of exit reason

    Use RestartSec= to set the number of seconds to wait before restarting, preventing rapid restart loops when a service is failing.

    ExecStart= defines the command to execute when the service starts. Note that absolute paths must be used:

    Correct — using absolute paths
    ExecStart=/usr/bin/python3 /opt/myapp/server.py

    For Type=oneshot services, you can specify multiple ExecStart= lines, which are executed sequentially.

    The [Install] section defines the behavior when systemctl enable is executed:

    Common [Install] section options
    [Install]
    WantedBy=multi-user.target
    Alias=myapp.service
    DirectiveDescription
    WantedBy=Specifies which target this service is enabled under (most commonly multi-user.target)
    RequiredBy=Similar to WantedBy, but establishes a hard dependency
    Alias=Creates an alias for the service

    The following example demonstrates how to create a complete systemd service using a Go web application.

    Create a custom service unit file
    sudo vim /etc/systemd/system/mywebapp.service

    Enter the following content:

    /etc/systemd/system/mywebapp.service
    [Unit]
    Description=My Go Web Application
    Documentation=https://example.com/mywebapp
    After=network.target
    Wants=network-online.target
    [Service]
    Type=simple
    User=webadmin
    Group=webadmin
    WorkingDirectory=/opt/mywebapp
    ExecStart=/opt/mywebapp/mywebapp
    ExecReload=/bin/kill -HUP $MAINPID
    Restart=on-failure
    RestartSec=10
    StandardOutput=journal
    StandardError=journal
    SyslogIdentifier=mywebapp
    # Security hardening
    NoNewPrivileges=true
    ProtectSystem=full
    ProtectHome=true
    PrivateTmp=true
    # Resource limits
    LimitNOFILE=65536
    MemoryMax=512M
    [Install]
    WantedBy=multi-user.target

    After creating or modifying a unit file, you must notify systemd to reload its configuration:

    Reload the systemd daemon configuration
    sudo systemctl daemon-reload
    Enable at boot and start the service immediately
    sudo systemctl enable --now mywebapp.service
    View the service running status
    sudo systemctl status mywebapp.service
    View service logs
    sudo journalctl -u mywebapp.service -f

    If you need to modify a service configuration installed by a package, do not edit the files under /usr/lib/systemd/system/ directly (they may be overwritten during system updates). Instead, use the drop-in override mechanism:

    Create an override configuration with systemctl edit
    sudo systemctl edit nginx.service

    This opens an editor and creates the file /etc/systemd/system/nginx.service.d/override.conf. For example, to add a memory limit:

    override.conf example — adding a memory limit
    [Service]
    MemoryMax=1G

    After saving and exiting, daemon-reload is executed automatically.

    To view the complete merged configuration (original + overrides):

    View the full merged unit configuration
    systemctl cat nginx.service

    Some tasks only need to run once, such as system initialization scripts:

    /etc/systemd/system/init-database.service
    [Unit]
    Description=Initialize Application Database
    After=postgresql.service
    Requires=postgresql.service
    [Service]
    Type=oneshot
    ExecStart=/opt/myapp/init-db.sh
    RemainAfterExit=yes
    User=postgres
    [Install]
    WantedBy=multi-user.target

    RemainAfterExit=yes means that after the process exits, the service status still shows as active, preventing other services that depend on it from being affected.

    When a service fails to start properly, follow these troubleshooting steps:

    View detailed service status and recent logs
    sudo systemctl status mywebapp.service -l
    View the full service log (without truncating long lines)
    sudo journalctl -u mywebapp.service --no-pager -n 50
    Verify that the unit file syntax is correct
    sudo systemd-analyze verify /etc/systemd/system/mywebapp.service
    View all properties of the service
    systemctl show mywebapp.service