Шаг 5 · Деплой · 40 минут

Переносим бота на VPS и оставляем работать 24/7

Локальный запуск заканчивается вместе с ноутбуком. На сервере Docker будет автоматически поднимать приложение после сбоя или перезагрузки.

Как будет выглядеть результат

Код лежит в /home/deploy/app, секреты — в отдельном .env, приложение работает внутри контейнера, а политика restart: unless-stopped возвращает его к жизни.

1. Выбираем конфигурацию

Для обычного Telegram‑бота без локальной нейросети начните с 1 vCPU, 1–2 ГБ RAM и 15–20 ГБ SSD. AI вызывается через внешний API, поэтому мощная видеокарта серверу не нужна. Если памяти станет мало, ресурсы можно увеличить позже.

2. Проверяем фундамент

К этому моменту желательно пройти статьи про Ubuntu, SSH и Docker. Быстрая проверка:

whoami
docker version
docker compose version
sudo ufw status

Работаем под deploy, не под root. Docker должен отвечать без ошибки доступа.

3. Переносим проект

Если код хранится в Git:

cd ~
git clone URL_ВАШЕГО_РЕПОЗИТОРИЯ app
cd app

Если репозитория нет, выполните на своём компьютере:

scp -r ./папка-проекта deploy@IP_СЕРВЕРА:/home/deploy/app

Не переносите локальную .venv: контейнер установит зависимости заново.

4. Готовим файлы запуска

Зафиксируйте зависимости:

aiogram
python-dotenv
openai

Сохраните как requirements.txt. Затем создайте Dockerfile:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "bot.py"]

И compose.yaml:

services:
  bot:
    build: .
    env_file: .env
    restart: unless-stopped
    logging:
      options:
        max-size: "10m"
        max-file: "3"

5. Создаём секреты на сервере

nano .env
chmod 600 .env

Вставьте токены. Команда chmod 600 разрешает читать файл только владельцу. Проверьте, что .env есть в .gitignore.

6. Собираем и запускаем

docker compose config
docker compose up -d --build
docker compose ps
docker compose logs --tail=100

config проверяет структуру Compose, но может показать подставленные переменные — не публикуйте вывод. В ps состояние должно быть Up.

Теперь напишите боту. Если он ответил, перезагрузите VPS:

sudo reboot

Через минуту подключитесь и выполните docker compose ps. Контейнер должен подняться самостоятельно.

7. Обновляем без хаоса

cd ~/app
git pull
docker compose build --pull
docker compose up -d
docker compose logs --tail=100
docker image prune -f

Сначала получите код, затем соберите новый образ, переключите контейнер и проверьте журнал. Старый образ не удаляйте до проверки, если вам нужен быстрый откат.

8. Если бот молчит

docker compose ps -a
docker compose logs --tail=200 bot
docker inspect --format='{{.State.ExitCode}}' app-bot-1
free -h
df -h
  • Exit code 1 обычно означает ошибку программы.
  • Exit code 137 часто связан с нехваткой памяти.
  • no space left on device — заполнен диск.
  • Два экземпляра polling‑бота конфликтуют — оставьте один.
Не запускайте второй экземпляр командой python bot.py рядом с контейнером. Для диагностики используйте логи Docker.

Что дальше

Для webhook или сайта подключите домен, Nginx и HTTPS →