Деплой Docker-приложения на VPS: пошаговое руководство 2026

Контейнеры стали стандартным способом доставки приложений в production: одинаковое окружение на ноутбуке и на сервере, быстрый откат версий, изоляция зависимостей. В 2026 году деплой Docker на VPS — must-have навык для backend-разработчика на Python, Node.js, Go или PHP. Это дешевле managed Kubernetes на старте и понятнее, чем «голый» systemd с десятком venv. В этом руководстве — полный цикл: от чистого VPS до работающего приложения за reverse proxy с HTTPS, плюс best practices для эксплуатации.

Когда Docker на VPS — правильный выбор

  • Несколько сервисов: API + worker + Redis + PostgreSQL.
  • Нужна воспроизводимость деплоя из CI/CD.
  • Команда без выделенного DevOps, но с Dockerfile в репозитории.
  • План миграции в Kubernetes позже — Docker Compose как промежуточный этап.

Когда Docker избыточен: один простой скрипт или static site — достаточно nginx и systemd. Для Java-стека те же идеи развиты в статье про контейнеризацию Java и Kubernetes.

Что понадобится на VPS

  • Ubuntu 22.04/24.04 LTS (или Debian 12).
  • Минимум 2 GB RAM для app + БД в Compose; 1 GB — только для одного лёгкого контейнера.
  • 20+ GB SSD/NVMe.
  • Домен с A-записью на IP сервера.
  • SSH-доступ по ключу.

VPS можно взять у Beget, Timeweb или другого провайдера. Для связки с другими материалами prizraks.ru: Beget VPS через prizraks.ru/go/beget.

Шаг 1: Базовая настройка сервера

После первого входа:

  • Создайте пользователя с sudo, отключите root-login по SSH.
  • Настройте ufw: allow OpenSSH, allow 80, allow 443, enable.
  • Обновите пакеты: apt update && apt upgrade -y.
  • Установите fail2ban (опционально, но рекомендуется).
  • Задайте timezone: timedatectl set-timezone Europe/Moscow.

Шаг 2: Установка Docker Engine и Compose

Официальный способ — репозиторий Docker (не путать с устаревшим docker.io из дистрибутива без compose plugin):

  • Установите Docker CE, containerd, docker-buildx-plugin, docker-compose-plugin.
  • Добавьте пользователя в группу docker, перелогиньтесь.
  • Проверка: docker run hello-world, docker compose version.

В 2026 используйте Compose V2 (docker compose, не отдельный бинарник docker-compose v1).

Шаг 3: Структура проекта

Типичный репозиторий:

  • Dockerfile — multi-stage для Python/Node (build → slim runtime).
  • docker-compose.yml — сервисы app, db, redis, nginx.
  • .env — секреты (не в Git), .env.example — шаблон.
  • nginx/conf.d/app.conf — reverse proxy.

Пример multi-stage Dockerfile (Python/FastAPI)

Stage build: установка зависимостей в venv. Stage production: копирование venv и кода, non-root user, CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"].

docker-compose.yml

  • app — build context, env_file, depends_on db/redis.
  • db — postgres:16-alpine, volume для данных.
  • redis — redis:7-alpine.
  • nginx — ports 80:80, 443:443, volumes config + certbot.

Шаг 4: Первый запуск на VPS

  1. Клонировать репозиторий: git clone ... /opt/myapp
  2. Скопировать .env.example.env, заполнить пароли.
  3. docker compose build
  4. docker compose up -d
  5. docker compose ps — все healthy.
  6. Логи: docker compose logs -f app

Для Telegram-бота в контейнере webhook проксируется так же, как без Docker — см. деплой Telegram-бота для логики webhook; здесь фокус на контейнерной обёртке.

Шаг 5: Nginx и SSL (Let’s Encrypt)

Вариант A: nginx на хосте

Nginx установлен на VPS, проксирует на 127.0.0.1:PORT, который проброшен из compose. Certbot —nginx на хосте.

Вариант B: nginx в контейнере + certbot

Используйте nginx-proxy + acme-companion или traefik с automatic HTTPS. Для простоты часто nginx на хосте + compose только для app/db.

После SSL проверьте редирект HTTP→HTTPS и заголовки HSTS для production.

Шаг 6: Миграции и фоновые worker’ы

  • Миграции БД: docker compose exec app alembic upgrade head или python manage.py migrate.
  • Celery worker — отдельный сервис в compose с тем же image, другой command.
  • Не запускайте migrate при каждом старте контейнера в production без контроля — лучше явно из CI/CD или deploy script.

Сравнение подходов к деплою Docker на VPS

Подход Сложность Zero-downtime Кому подходит
docker compose up -d вручную Низкая Нет (краткий простой) Solo, staging, MVP
Deploy script + git pull + compose Средняя Минимальный простой Малые команды
Watchtower / auto-pull Низкая Нет Небольшие pet-projects (осторожно в prod)
GitHub Actions SSH deploy Средняя Частично (rolling вручную) Регулярные релизы
Blue-green два compose project Высокая Да Критичный uptime
Kubernetes Очень высокая Да Масштаб, many services

CI/CD: GitHub Actions → VPS

Типовой pipeline:

  1. Push в main → test job (pytest, lint).
  2. Build Docker image → push в GitHub Container Registry или Docker Hub.
  3. SSH на VPS: docker compose pull && docker compose up -d.
  4. Опционально: health check curl на /health.

Секреты: SSH private key, registry token — в GitHub Secrets. На VPS не храните пароли registry в plain text.

Безопасность Docker на VPS

  • Не запускайте контейнеры от root внутри — USER в Dockerfile.
  • Не публикуйте порты БД наружу (5432:5432 только на localhost или internal network).
  • Docker socket (/var/run/docker.sock) — не монтировать в app-контейнер без крайней нужды.
  • Регулярно docker compose pull для base images с патчами.
  • Scan образов: Trivy, Docker Scout.
  • Limit resources в compose: mem_limit, cpus.
  • Read-only filesystem где возможно, cap_drop ALL.

Логи, мониторинг, бэкапы

Логи

json-file driver с rotation (max-size, max-file). Централизация: Loki, или простой vector → файл. Application logs в stdout/stderr — twelve-factor way.

Мониторинг

Prometheus node_exporter на хосте, cAdvisor для контейнеров, Uptime Kuma для HTTP checks. Алерты в Telegram админу — пересекается с практикой из bot-гайдов на prizraks.ru.

Бэкапы

  • Volume PostgreSQL: nightly pg_dump в S3 или второй сервер.
  • Конфиг nginx и .env — encrypted backup.
  • Тест восстановления раз в квартал — backup без restore бесполезен.

Оптимизация образов

  • Multi-stage build — маленький финальный слой.
  • .dockerignore — не тащить .git, tests, __pycache__.
  • Pin версий base image (python:3.12-slim-bookworm).
  • Кэш слоёв: сначала COPY requirements, pip install, потом код.
  • Alpine vs slim — slim проще для Python с native wheels.

ML-сервисы с GPU (YOLO inference) на VPS без GPU используют CPU-образы; см. YOLO11 — модель в контейнере, но железо должно соответствовать нагрузке.

Типичные проблемы и решения

Проблема Причина Решение
502 Bad Gateway App не слушает или упал logs app, проверить bind 0.0.0.0, healthcheck
Cannot connect to db Неверный host (db vs localhost) В compose использовать service name как hostname
Permission denied volume UID mismatch chown или user в Dockerfile совпадает с volume
Диск заполнен Старые образы docker system prune -a (осторожно), log rotation
OOM killed Мало RAM Увеличить VPS или limits, отделить БД

Обновление приложения без простоя (упрощённо)

  1. Build новый image с тегом версии.
  2. docker compose up -d --no-deps app — пересоздать только app.
  3. Health check OK — готово; fail — откат image tag предыдущий.

Для БД backward-compatible migrations сначала, deploy app потом — expand/contract pattern.

Docker Compose vs Swarm vs Kubernetes

На одном VPS в 2026 Compose покрывает 80% задач SMB. Swarm почти не используют greenfield. Kubernetes оправдан при нескольких нодах, autoscaling, service mesh — иначе overhead съест бюджет. Путь роста: Compose на VPS → managed k8s (или self-hosted) при доказанной необходимости.

Связь с обучением и архитектурой

Контейнеры не отменяют fundamentals: структура кода, ООП, тесты. Основы ООП помогают проектировать сервисы, которые удобно упаковывать в образы. Pet-project с Dockerfile в GitHub — сильный сигнал employer’у.

Чеклист production-ready деплоя

  • Dockerfile multi-stage, non-root user
  • compose с healthcheck для app и db
  • .env вне Git, secrets в CI
  • nginx + HTTPS, автообновление cert
  • Миграции под контролем deploy script
  • Бэкапы БД и тест restore
  • Мониторинг uptime и disk
  • Документированный rollback

Пример docker-compose для Python API + PostgreSQL

Концептуальная структура (адаптируйте под проект):

  • services.app — build: ., ports не публиковать наружу, только expose 8000 в internal network.
  • services.db — image postgres:16-alpine, environment POSTGRES_PASSWORD из env, volume pgdata.
  • services.redis — для cache/queue если нужно.
  • networks — default bridge или явная internal network.

На хосте nginx проксирует 443 → app:8000 через published port только на 127.0.0.1:8000:8000 — так БД не светится в интернет.

Watchtower и автоматические обновления: осторожно

Watchtower тянет новые образы и перезапускает контейнеры — удобно для homelab, рискованно для production без staging. Если используете — pin digest образа, тестируйте в CI, включайте уведомления о перезапуске. Предсказуемее deploy по webhook из GitHub Actions.

Несколько окружений на одном VPS

Staging и production: два каталога /opt/app-staging, /opt/app-prod, разные compose project name (docker compose -p staging), разные env и subdomain. Общий nginx vhost маршрутизирует по Host header. Экономия на втором VPS, но blast radius выше — ошибка в nginx config заденет оба.

SELinux и AppArmor на Ubuntu

На stock Ubuntu обычно не мешают Docker. Если включён hardening — проверьте профили для container runtime. Типичная ошибка после hardening — nginx не может connect к upstream; смотрите audit.log.

Связка Docker на VPS и Beget для смешанных проектов

Частая схема: Laravel или legacy PHP на managed/shared Beget, новый Python microservice в Docker на VPS. DNS: api.domain.ru → VPS, domain.ru → shared. SSL на обоих. Единый мониторинг Uptime Kuma на VPS. Beget для legacy: prizraks.ru/go/beget.

Часто задаваемые вопросы

Как деплоить Docker на VPS в 2026?

Установите Docker Engine и Compose plugin, клонируйте репозиторий с Dockerfile и compose, настройте .env, docker compose up -d, nginx + Certbot для HTTPS.

Нужен ли Kubernetes для одного приложения?

Нет. Docker Compose на VPS достаточно до появления требований к autoscaling и multi-node.

Где хостить VPS для Docker?

Любой провайдер с 2+ GB RAM: Beget, Timeweb, Selectel. Beget: https://prizraks.ru/go/beget.

Как обновить контейнеры?

git pull, docker compose build --pull, docker compose up -d. В CI — push image и pull на сервере.

Безопасно ли хранить .env на сервере?

Да, с правами 600 и пользователем deploy. Лучше Docker secrets или vault при росте команды.

PostgreSQL в Docker для production?

Допустимо на SMB VPS с бэкапами и named volume. При высоких SLA — managed DB провайдера.

Как деплоить Python-бота в Docker?

Образ с aiogram/PTB, webhook через nginx, переменные BOT_TOKEN в env. Логика бота: гайд на prizraks.ru.

На prizraks.ru мы деплоим Docker-приложения для клиентов: CRM, API, боты и пайплайны автоматизации. Нужен аудит текущего VPS или настройка CI/CD под ключ — напишите через сайт, разберём стек и соберём воспроизводимый деплой.

Где разместить проект

Для Python, PHP, ботов и pet-проектов мы рекомендуем Beget — SSH, Python, cron и поддержка 24/7 от 150 ₽/мес.

Перейти на Beget →

Хотите системно изучить программирование?

Подборка онлайн-курсов для разработчиков — Python, Java, веб и DevOps.

Смотреть курсы →

Нужна помощь с разработкой?

Автоматизация, CRM, Telegram-боты, деплой и техподдержка 24/7.

Телефон: 8 918 532 81 08 · Заказать услугу

Статья может содержать партнёрские ссылки. Это не влияет на стоимость для вас, но помогает развивать блог.