Базовый деплой
чтобы работало без тебя и переживало перезагрузку
Что это
Деплой — вынести код туда, где он работает постоянно: на сервер, а не на твоём ноутбуке с открытым терминалом.
Статья даёт минимум, которого хватает для бота или небольшого сервиса. Не Kubernetes и не облачные платформы — простая схема, которую можно понять целиком и починить руками.
Как выглядит в коде
Что должно быть готово до переноса
| Готово | Зачем |
|---|---|
requirements.txt актуален | чтобы поставить то же самое (статья 5.6) |
| Секреты из окружения | чтобы не тащить .env в репозиторий (5.7) |
.gitignore настроен | чтобы не уехало лишнее |
| Код в git | чтобы обновлять git pull, а не копированием файлов |
Логи через logging | иначе на сервере не узнаешь, что случилось (4.2) |
Если хоть одного пункта нет, деплой превратится в отладку вслепую.
Перенос
git clone <адрес> /opt/weather-bot
cd /opt/weather-bot
python3 -m venv .venv
.venv/bin/pip install -r requirements.txtСекреты создаются на сервере отдельно, руками:
nano .env # вписать BOT_TOKEN
chmod 600 .env # читать может только владелецАвтозапуск
Запущенный в терминале процесс умрёт, когда ты закроешь ssh. Нужно, чтобы система запускала его сама — и перезапускала после падения и перезагрузки. В Linux для этого есть systemd.
Файл /etc/systemd/system/weather-bot.service:
[Unit]
Description=Weather bot
After=network.target
[Service]
WorkingDirectory=/opt/weather-bot
EnvironmentFile=/opt/weather-bot/.env
ExecStart=/opt/weather-bot/.venv/bin/python bot.py
Restart=always
RestartSec=5
User=botuser
[Install]
WantedBy=multi-user.targetПострочно:
WorkingDirectory— папка, из которой запускается; относительные пути в коде считаются отсюда;EnvironmentFile— откуда взять переменные окружения, то есть секреты;ExecStart— полный путь к Python из виртуального окружения, не системный;Restart=always+RestartSec=5— перезапускать при падении, с паузой в пять секунд;User— от чьего имени работает; неroot.
Команды:
sudo systemctl daemon-reload # перечитать файлы служб
sudo systemctl enable weather-bot # запускать при загрузке
sudo systemctl start weather-bot # запустить сейчас
sudo systemctl status weather-bot # как дела
sudo journalctl -u weather-bot -f # смотреть логи вживуюПоследняя команда — основная при отладке на сервере. Она и есть замена
print на боевой машине.
Обновление
cd /opt/weather-bot
git pull
.venv/bin/pip install -r requirements.txt
sudo systemctl restart weather-bot
sudo journalctl -u weather-bot -n 50Четыре команды плюс проверка логов. Последняя строка обязательна: обновление без проверки — это деплой вслепую.
Как сказать ИИ
Составь systemd-юнит для этого проекта. Путь /opt/weather-bot,
запуск bot.py из .venv, секреты из .env, перезапуск при падении,
не от root. Объясни каждую строку.Бот перезапускается каждые несколько секунд. Вот вывод
journalctl за последнюю минуту. Что происходит?
<лог>Напиши скрипт обновления: git pull, зависимости, перезапуск,
показать последние 50 строк лога. Если git pull ничего
не подтянул — ничего не делать.На что смотреть
.env на сервере отсутствует. Служба стартует и сразу падает. В логах —
то самое понятное сообщение из статьи 5.7, если оно написано.
Системный Python вместо .venv. В ExecStart указан /usr/bin/python3 —
библиотек проекта там нет.
Относительные пути. Код открывает data/bot.db, а служба запущена из
другой папки. Отсюда WorkingDirectory.
Запуск от root. Ошибка в коде получает права на всю систему. Отдельный пользователь — пять минут работы.
Нет ротации логов. journalctl сам ограничивает размер, а вот логи в
собственный файл растут бесконечно, пока не кончится диск.
Обновление копированием файлов. Через месяц на сервере не та версия, что в git, и никто не знает какая.
Шпаргалка
До переноса: requirements, секреты из окружения,
.gitignore, git, логи.Секреты создаются на сервере руками,
chmod 600.systemd:
WorkingDirectory,EnvironmentFile, полный путь к.venv,Restart=always, не root.Логи:
journalctl -u <служба> -f.Обновление:
git pull→ зависимости →restart→ посмотреть логи.Restart=alwaysпрячет падения: проверяй логи, а не наличие процесса.