Skip to main content

Systemd Service Specification

The service unit ID comes from config.ini.system_id:

{
"system_id": "<system_id>"
}

The final system service must be:

<system_id>.service

Retained within the application installation directory:

/usr/local/<app_id>/init.d/<system_id>.service

Standard Service File:

Standard Service File (with security hardening):

[Unit]
Description=<service_description>
After=network.target
StartLimitBurst=5
StartLimitIntervalSec=60

[Service]
Type=simple
User=<appid>
Group=<appid>
WorkingDirectory=/usr/local/<appid>
ExecStart=/usr/local/<appid>/bin/<binary_name>
EnvironmentFile=/usr/local/<appid>/<appid>.env
TimeoutStartSec=30
TimeoutStopSec=10
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/<appid> /var/log/<appid>
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Systemd Directive Reference:

DirectiveValueRequiredDescription
User<appid>✅ YesRun the service as a dedicated non-root user
Group<appid>✅ YesRun the service with a dedicated group
WorkingDirectory/usr/local/<appid>✅ YesWorking directory for the service
NoNewPrivilegestrue✅ YesPrevent privilege escalation
ProtectSystemstrict✅ YesMount /usr, /boot, /etc as read-only
ProtectHometrue✅ YesHide the /home directory
TimeoutStartSec30✅ YesService startup timeout (seconds)
TimeoutStopSec10✅ YesGraceful stop timeout (seconds)
AmbientCapabilitiesCAP_NET_BIND_SERVICEConditionalOnly needed when binding to ports below 1024
ReadWritePaths/var/lib/<appid> /var/log/<appid>✅ YesExplicitly declare writable paths
LimitNOFILE65536RecommendedFile descriptor limit
StartLimitBurst5RecommendedMaximum restart count within the interval
StartLimitIntervalSec60RecommendedRestart limit interval (seconds)
Important

The service unit configuration file must not configure Restart and RestartSec parameters. The application's start, stop, and restart lifecycle is uniformly managed by the TOS App Center. Developer-configured auto-restart strategies may conflict with the platform management logic, leading to inconsistent application states. StartLimitBurst and StartLimitIntervalSec are retained and unaffected.