Для фонового приложения на Ubuntu удобно использовать systemd. Сервис можно запускать автоматически после перезагрузки, ограничивать права, читать его журнал и наблюдать за состоянием без самодельного nohup.

Пример unit-файла

Пример рассчитан на уже созданного непривилегированного пользователя appsvc и готовый бинарник /opt/example/bin/server:

[Unit]
Description=Example application
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=appsvc
Group=appsvc
WorkingDirectory=/opt/example
ExecStart=/opt/example/bin/server
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true

[Install]
WantedBy=multi-user.target

Ограничения ProtectSystem и ProtectHome подходят не каждому сервису. Если приложению нужны каталоги для записи, явно перечислите их через ReadWritePaths= или используйте StateDirectory=.

Проверка и запуск

Сохраните файл в /etc/systemd/system/example.service, затем:

sudo systemctl daemon-reload
sudo systemctl enable --now example.service
systemctl status example.service
journalctl -u example.service -n 100 --no-pager

В журнале ищите не только ошибку завершения, но и сообщения приложения о готовности. Для сетевых приложений полезно отдельно проверять доступность endpoint и корректность ответа.

Несколько практических правил

Не запускайте сетевой сервис от root, если этого не требует архитектура. Не вставляйте пароли напрямую в ExecStart. Фиксируйте версии бинарников, сохраняйте unit-файл в системе контроля версий без секретов и проверяйте запуск после тестовой перезагрузки.