Для фонового приложения на 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-файл в системе контроля версий без секретов и проверяйте запуск после тестовой перезагрузки.