Если сделать вот так
./main &
- тогда при завершении ssh сессии отвалится и сам демон.
Всё действительно сильно зависит от ОС.
Если говорить о Linux и о самом простом способе, то можно вот так
nohup ./main > error.log 2>&1 &
Этот способ подходит для любых бинарников, которые не делают fork, т.е. ведут себя также, как и Go'шный http ListenAndServe.
Второй вариант - это запуск сервиса через systemd или init.d в зависимости от того, какой в вашем Linux.
Я предпочитаю именно этот вариант, особенно, когда нельзя использовать Docker (например на виртуальных машинах с Virtuozzo).
Для systemd (например на CentOS) можно создать файл /etc/systemd/system/yourservice.conf примерно такого содержания
[Unit]
Description=YourServie
After=network.target
After=syslog.target
[Service]
User=nobody # user ID под которым должен работать ваш демон
Group=nobody
Type=simple
WorkingDirectory=/opt/yourservice
ExecStart=/opt/yourservice/yourservice >> /var/log/yourservice.log 2>&1
Restart=always
[Install]
WantedBy=multi-user.target
Третий вариант - использовать Docker, инструкций много в интернете, если этот вариант актуален - напишите, я помогу найти нормальную.
Четвёртый вариант, который обычно используется в ПО типа Nginx и т.д.
В общем случае нужно:
- породить новый процесс, т.е. сделать fork (вызвать системный вызов)
- настроить вывод stdout, stderr в файлы (опционально)
- "отвязаться от сессии" вызвать системный вызов setsid
- сделать chdir куда нужно
- настроить обработку сигналов SIGINT, SIGTERM, чтобы иметь возможность корректно завершать работу или перечитывать конфиги
Возможно я что-то упустил в этом списке, давно уже демонов таким образом не делал, использую или Docker или systemd/init.d, так намного проще :)
Могу еще добавить, что 4й вариант для Go считается антипаттерном.
Вот тут
https://socketloop.com/tutorials/golang-daemonizin... есть пример, правда он не очень удачный, там очень много нюансов.