Назад к блогу
DevOps·11 марта 2026·Sayan Roor

Полное руководство: деплой веб-приложения с Docker, Nginx и SSL на продакшен-сервер

Пошаговая инструкция по развёртыванию веб-приложения на VPS: Docker Compose, Nginx reverse proxy, SSL-сертификаты Let's Encrypt, PostgreSQL, Redis, MinIO, мониторинг, бэкапы и CI/CD.

DockerNginxDevOpsDeploymentServer
Деплой веб-приложения с Docker и Nginx на сервер в 2026 году

Полное руководство: деплой веб-приложения с Docker, Nginx и SSL на продакшен-сервер

Пошаговая инструкция по развёртыванию приложения на VPS. Каждый шаг содержит команду, объяснение и ожидаемый результат. Подходит как для Next.js, NestJS, так и для любого другого стека.


Содержание

  1. Требования к серверу
  2. Архитектура проекта
  3. Подготовка сервера
  4. Установка Docker и Nginx
  5. Docker Compose: конфигурация сервисов
  6. Настройка Nginx как reverse proxy
  7. SSL-сертификаты Let's Encrypt
  8. PostgreSQL, Redis и MinIO в Docker
  9. Переменные окружения и секреты
  10. Настройка файрвола
  11. Мониторинг (Prometheus + Grafana)
  12. Автоматические бэкапы
  13. CI/CD через GitHub Actions
  14. Устранение неполадок
  15. Чеклист продакшена

1. Требования к серверу

Перед началом убедитесь, что у вас есть VPS с достаточными ресурсами.

ПараметрМинимумРекомендуется
CPU2 vCPU4 vCPU
RAM4 GB8 GB
Диск40 GB SSD80+ GB SSD
ОСUbuntu 22.04 LTSUbuntu 24.04 LTS
Сеть100 Mbps1 Gbps

Где арендовать сервер:

Также вам понадобится:

  • Домен (например your-domain.com) с доступом к DNS-настройкам
  • SSH-клиент (встроен в macOS/Linux, на Windows — PuTTY или Windows Terminal)

2. Архитектура проекта

Прежде чем начинать деплой, важно понимать как компоненты взаимодействуют:

        Пользователь (браузер)
              |
              v
    +-------------------+
    |  Nginx (:80/443)  |  <-- Принимает все запросы, раздаёт по адресам
    +----+----------+---+
         |          |
         v          v
   +----------+  +----------+
   |   Web    |  |   API    |
   | (Next.js)|  | (NestJS) |  <-- Приложения в Docker-контейнерах
   |  :3000   |  |  :3001   |
   +----------+  +--+-+-+---+
                    | | |
          +---------+ | +--------+
          v           v          v
   +----------+ +----------+ +---------+
   |PostgreSQL| |  Redis   | |  MinIO  |
   |   (БД)   | |  (кэш)  | | (файлы) |
   |  :5432   | |  :6379   | |  :9000  |
   +----------+ +----------+ +---------+

Роль каждого компонента:

  • Nginx — принимает запросы из интернета, терминирует SSL и проксирует к контейнерам
  • Web — фронтенд (SSR/SSG), то что видит пользователь
  • API — серверная логика (авторизация, данные, файлы)
  • PostgreSQL — основная база данных
  • Redis — кэширование и очереди
  • MinIO — S3-совместимое хранилище файлов

3. Подготовка сервера

3.1. Подключение к серверу

3.2. Обновление системы

Скачивает и устанавливает все обновления безопасности. Занимает 1-3 минуты.

3.3. Установка базовых утилит

Что мы установили:

  • curl, wget — скачивание файлов
  • git — управление кодом
  • htop — мониторинг нагрузки
  • ufw — файрвол
  • fail2ban — защита от перебора паролей

3.4. Создание deploy-пользователя

Работать под root опасно — одна ошибка может сломать весь сервер. Создаём отдельного пользователя.

3.5. Настройка SSH-ключа

3.6. Защита SSH

Откройте конфигурацию SSH:

Измените следующие строки:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3

Перезапустите SSH:

Важно: перед закрытием текущей сессии откройте новый терминал и проверьте, что можете подключиться: ssh deploy@YOUR_SERVER_IP

3.7. Переключение на deploy-пользователя

С этого момента все команды выполняем от имени deploy:


4. Установка Docker и Nginx

4.1. Docker

Проверка:

Ожидаемый результат:

Docker version 27.x.x, build ...
Docker Compose version v2.x.x

4.2. Nginx

Проверка:

Должна быть строка Active: active (running).

4.3. Certbot (для SSL)


5. Docker Compose: конфигурация сервисов

Создайте файл docker-compose.prod.yml в корне вашего проекта. Это главный файл, описывающий все сервисы.

Обратите внимание: все порты инфраструктуры привязаны к 127.0.0.1 — они не доступны из интернета напрямую, только через Nginx.


6. Настройка Nginx как reverse proxy

Nginx принимает запросы из интернета и направляет их к Docker-контейнерам. Без Nginx сайт не будет доступен по домену.

6.1. Конфигурация для основного сайта

Важно: создаём конфиги только с HTTP (порт 80). SSL-блоки добавит certbot автоматически.

6.2. Конфигурация для API

6.3. Активация конфигов

6.4. Проверка и перезагрузка

Ожидаемый результат:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

7. SSL-сертификаты Let's Encrypt

SSL шифрует соединение между пользователем и сервером. Без него браузер показывает предупреждение «Небезопасный сайт». Let's Encrypt выдаёт бесплатные сертификаты.

7.1. Настройка DNS

Перед получением сертификатов убедитесь, что DNS-записи настроены:

ТипИмяЗначениеTTL
A@YOUR_SERVER_IP3600
AwwwYOUR_SERVER_IP3600
AapiYOUR_SERVER_IP3600

Проверка:

7.2. Получение сертификатов

Certbot спросит email и предложит перенаправление HTTP на HTTPS — выберите «Redirect».

7.3. Проверка автопродления

Ожидаемый результат: Congratulations, all simulated renewals succeeded

Сертификаты автоматически продляются каждые 60 дней. Ничего дополнительно делать не нужно.


8. PostgreSQL, Redis и MinIO в Docker

8.1. Запуск инфраструктуры

Сначала запускаем базовые сервисы, от которых зависит приложение:

Подождите 15 секунд для инициализации БД:

8.2. Проверка

Все 3 сервиса должны быть в статусе Up (healthy).

8.3. Настройка MinIO

Установите MinIO Client:

Подключитесь и создайте бакет:

8.4. Сборка и запуск приложения

8.5. Инициализация базы данных

Ожидаемый результат: Your database is now in sync with your Prisma schema.


9. Переменные окружения и секреты

9.1. Генерация секретов

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

9.2. Файл .env

Создайте файл .env рядом с docker-compose.prod.yml:

Безопасность: никогда не коммитьте файл .env в Git. Добавьте его в .gitignore.


10. Настройка файрвола

Файрвол блокирует все порты кроме необходимых. Без него любой может подключиться к базе данных напрямую!

Проверка:

Ожидаемый результат:

Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere

Порты 3000, 3001, 5432, 6379, 9000 НЕ открыты наружу — они доступны только через Nginx.

Настройка fail2ban

После 3 неудачных попыток входа IP-адрес блокируется на 1 час.


11. Мониторинг (Prometheus + Grafana)

Мониторинг опционален, но настоятельно рекомендуется для продакшена.

11.1. Добавление сервисов мониторинга в Docker Compose

Добавьте следующие сервисы в ваш docker-compose.prod.yml:

11.2. Запуск мониторинга

11.3. Что мониторить

МетрикаОписаниеПорог алерта
CPU сервераНагрузка на процессор> 80%
RAMИспользование памяти> 85%
ДискЗаполненность диска> 90%
PostgreSQLАктивные подключения> 80
RedisИспользование памяти> 200 MB
APIВремя ответа, ошибки 5xx> 2s / > 1%

12. Автоматические бэкапы

Правило: если вы не проверяли восстановление — бэкапа не существует.

12.1. Скрипт бэкапа

12.2. Автоматический запуск (cron)

Добавьте строку:

0 3 * * * /home/deploy/backup.sh >> /home/deploy/backups/backup.log 2>&1

Бэкап будет выполняться каждый день в 3:00.

12.3. Восстановление из бэкапа


13. CI/CD через GitHub Actions

13.1. Подготовка SSH-ключа

На сервере:

Скопируйте приватный ключ.

13.2. Секреты в GitHub

Перейдите: Settings > Secrets and variables > Actions > New repository secret

Имя секретаЗначение
DEPLOY_HOSTIP-адрес сервера
DEPLOY_USERdeploy
DEPLOY_SSH_KEYПриватный ключ

13.3. GitHub Actions Workflow

Создайте файл .github/workflows/deploy.yml:

Теперь при пуше в main приложение автоматически обновится на сервере.


14. Устранение неполадок

502 Bad Gateway

Nginx работает, но приложение не запущено или упало.

Connection Refused

Nginx не работает.

Нехватка RAM при сборке

Docker-сборка требует ~2 GB RAM. Добавьте swap:

Контейнер постоянно перезапускается

Типичные причины:

  • Неправильные переменные в .env
  • БД недоступна
  • Порт уже занят

Нехватка дискового пространства

Полезные команды для диагностики


15. Чеклист продакшена

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

  • SSH: отключён root-логин, только ключи
  • UFW: открыты только порты 22, 80, 443
  • fail2ban настроен и запущен
  • SSL-сертификаты установлены и автопродляются
  • JWT-секреты уникальны
  • Пароль БД сгенерирован
  • Пароль MinIO сгенерирован
  • .env файлы не в Git

Инфраструктура

  • PostgreSQL работает (healthcheck зелёный)
  • Redis работает (healthcheck зелёный)
  • MinIO работает, бакет создан
  • Nginx настроен как reverse proxy
  • Порты инфраструктуры привязаны к 127.0.0.1

Приложение

  • Сайт открывается по HTTPS
  • API отвечает на health-эндпоинт
  • Авторизация работает
  • Загрузка файлов работает
  • CORS настроен на правильный домен

Обслуживание

  • Cron-бэкап настроен (ежедневно)
  • Тестовое восстановление проведено
  • CI/CD workflow работает
  • Мониторинг настроен (опционально)
  • Алерты на критические метрики

Заключение

Вы развернули полноценное продакшен-окружение:

  1. Сервер — защищённый, с отдельным deploy-пользователем
  2. Docker Compose — все сервисы изолированы и воспроизводимы
  3. Nginx — reverse proxy с кэшированием статики
  4. SSL — бесплатные сертификаты Let's Encrypt с автопродлением
  5. Файрвол — только необходимые порты открыты
  6. Бэкапы — автоматические, ежедневные, с ротацией
  7. CI/CD — автоматический деплой при пуше в main
  8. Мониторинг — метрики и алерты через Grafana

Эта архитектура выдерживает до 10 000 RPS при правильной настройке кэширования и горизонтальном масштабировании контейнеров. Удачного деплоя!

Sayan Roor

Full‑stack разработчик. Создаю веб‑приложения на Next.js и TypeScript с фокусом на производительность и конверсию.