Бот «не працює» на сервері двома способами. Очевидний: зупиняється, щойно ви закриваєте SSH. Підступний: працює собі два дні, падає о 4 ранку на якомусь необробленому винятку, і ви дізнаєтесь про це за години, коли хтось питає, чому він лежить. В обох одне рішення, і це не «не забувати перезапускати» — це передати роботу systemd, який тримає все живим за вас.
Чому помирає при виході
Якщо запустили python bot.py у SSH-сесії, процес — її нащадок. Закрили сесію — процес із нею. nohup і & маскують це, але не дають ні рестарту при падінні, ні старту при завантаженні — тож ви розв'язали дрібну проблему й зберегли велику.
Реальне рішення: systemd-сервіс
Це все цілком. Створіть /etc/systemd/system/mybot.service:
[Unit]
Description=My bot
After=network-online.target
[Service]
WorkingDirectory=/home/youruser/mybot
ExecStart=/home/youruser/mybot/venv/bin/python bot.py
Restart=always
RestartSec=5
User=youruser
Environment=API_KEY=...
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now mybot
Усю важку роботу роблять два рядки:
Restart=always— бот впав, systemd піднімає за 5 секунд. Та сама смерть о 4 ранку стає 5-секундним блиманням, якого ніхто не помічає.enable— стартує після перезавантаження сам. Без «о, сервер перезавантажився, а я забув усе перезапустити».
Якщо все ще барахлить — читайте логи
Бот, що крэш-лупить, не лагодиться «перезапустити сильніше»; щось реально не так. systemd ловить stdout/stderr, тож:
systemctl status mybot # живий/лежить, останній код виходу
journalctl -u mybot -n 100 # свіжі логи + помилка, на якій помер
journalctl -u mybot -f # стежити наживо
Причина майже завжди прямо там: відсутня змінна оточення, необроблений виняток, таймаут API, OOM-kill. Лагодьте її — Restart=always це страховка, не ліки від реального багу.
Підказка: якщо логи показують, що бота вбивають за пам'ять — ви переросли сервер, див. гайд по sizing.
Коли натомість підходять tmux чи pm2
systemd не єдина відповідь, просто найкращий дефолт:
- tmux — чудово для швидкого тесту чи спостереження за інтерактивним процесом. Запустив, від'єднався, повернувся. Але не перезапустить при падінні й не переживе перезавантаження — не для проду.
- pm2 — розумний, якщо вже у світі Node і хочете його дашборд процесів. Заковика: pm2 сам процес, який тепер треба тримати живим (зазвичай... через systemd). Для одного бота це зайвий шар.
Для одного постійного бота чи агента systemd — найпростіше, що реально працює: він уже на сервері, не вимагає зайвих інструментів і робить рестарт, старт-при-завантаженні й логування з коробки.
Чесний підсумок
Аптайм — не про сервер побільше чи більше дисципліни, а про те, щоб не прив'язувати процес до ноутбука. Оберніть у systemd-юніт із Restart=always і enable, і дивіться journalctl, коли щось не так. Зробіть це раз — і бот тримається, дивитесь ви чи спите. (Новий сервер? Спершу закрийте його — бот 24/7 це й мішень 24/7.)