// blog

Как настроить Nginx в качестве reverse proxy для контейнеров Docker: полное руководство

August 14, 2026 · by CLIQHOST

Как настроить Nginx в качестве reverse proxy для контейнеров Docker: полное руководство

Если вы запускаете несколько веб-приложений в Docker-контейнерах на одном сервере, вам нужен удобный способ открыть к ним доступ без необходимости пробрасывать десятки разных портов. Стандартное решение — Nginx в роли reverse proxy: он принимает входящие HTTP/HTTPS-запросы и перенаправляет их в нужный контейнер.

В этом руководстве вы узнаете, как настроить Nginx в качестве reverse proxy для Docker на VPS NVMe или VPS SSD шаг за шагом, с реальными примерами конфигурации и настройкой HTTPS.


Зачем нужен reverse proxy?

Без reverse proxy каждый Docker-контейнер должен слушать на своём уникальном порту (например, 3001, 3002, 8080). Это означает:

  • Некрасивые URL вида http://domain.md:3001
  • Сложность управления SSL-сертификатами для каждого сервиса
  • Прямое открытие портов в брандмауэре

Nginx как reverse proxy решает все эти проблемы: принимает весь трафик на портах 80 и 443, а затем перенаправляет его внутри сервера в нужный контейнер на основании имени домена или URL-пути.


Требования

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

  • VPS с Linux (рекомендуется Ubuntu 22.04 или Debian 12) — если его нет, закажите VPS NVMe у CLIQHOST
  • Установленные Docker и Docker Compose
  • Nginx, установленный на хосте (не в контейнере — в рамках данного руководства)
  • Права root или sudo
  • Домен, указывающий на IP вашего сервера
  • Действующий SSL-сертификат (или Let's Encrypt)

Шаг 1: Установите Nginx на сервер

Если Nginx ещё не установлен:

sudo apt update
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx

Проверьте статус:

sudo systemctl status nginx

Шаг 2: Запустите Docker-контейнеры

Допустим, у вас два приложения:

  • App1 — Node.js-приложение, слушающее на внутреннем порту 3000
  • App2 — Python/Flask-приложение на внутреннем порту 5000

Запускаем контейнеры, привязывая порты только к localhost:

# App1
docker run -d --name app1 -p 127.0.0.1:3000:3000 myapp1:latest

# App2
docker run -d --name app2 -p 127.0.0.1:5000:5000 myapp2:latest

Важно: Используем 127.0.0.1:PORT, чтобы привязать контейнер только к loopback-интерфейсу — порт недоступен снаружи, только с самого сервера (где работает Nginx).

Или через Docker Compose (docker-compose.yml):

version: '3.8'
services:
  app1:
    image: myapp1:latest
    ports:
      - "127.0.0.1:3000:3000"
    restart: unless-stopped

  app2:
    image: myapp2:latest
    ports:
      - "127.0.0.1:5000:5000"
    restart: unless-stopped
docker compose up -d

Шаг 3: Настройте Nginx как reverse proxy

Создайте отдельный файл конфигурации для каждого домена в /etc/nginx/sites-available/.

Конфигурация для App1 (app1.domain.md)

sudo nano /etc/nginx/sites-available/app1.domain.md
server {
    listen 80;
    server_name app1.domain.md;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Конфигурация для App2 (app2.domain.md)

sudo nano /etc/nginx/sites-available/app2.domain.md
server {
    listen 80;
    server_name app2.domain.md;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Активируйте конфигурации:

sudo ln -s /etc/nginx/sites-available/app1.domain.md /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/app2.domain.md /etc/nginx/sites-enabled/

Проверьте и перезагрузите Nginx:

sudo nginx -t
sudo systemctl reload nginx

Шаг 4: Добавьте HTTPS с Let's Encrypt

Установите Certbot и получите бесплатные SSL-сертификаты:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d app1.domain.md -d app2.domain.md

Certbot автоматически обновит файлы Nginx, добавив SSL-блоки и перенаправление HTTP → HTTPS.

После этого конфигурация для app1.domain.md будет выглядеть примерно так:

server {
    listen 443 ssl;
    server_name app1.domain.md;

    ssl_certificate /etc/letsencrypt/live/app1.domain.md/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app1.domain.md/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name app1.domain.md;
    return 301 https://$host$request_uri;
}

Для коммерческих проектов рассмотрите SSL-сертификаты OV/EV от CLIQHOST — с расширенной проверкой и гарантией.


Шаг 5: Сетевой подход Docker (продвинутый вариант)

Более чистый способ — поместить Nginx в отдельный контейнер и организовать взаимодействие через внутреннюю сеть Docker, не открывая порты на хосте.

version: '3.8'
networks:
  webnet:
    driver: bridge

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./certbot/www:/var/www/certbot
      - ./certbot/conf:/etc/letsencrypt
    networks:
      - webnet
    restart: unless-stopped

  app1:
    image: myapp1:latest
    expose:
      - "3000"
    networks:
      - webnet
    restart: unless-stopped

  app2:
    image: myapp2:latest
    expose:
      - "5000"
    networks:
      - webnet
    restart: unless-stopped

В этом случае в конфигурации Nginx вместо 127.0.0.1 используется имя сервиса:

location / {
    proxy_pass http://app1:3000;
}

Внутренний DNS Docker автоматически резолвит имя app1 в IP-адрес контейнера.


Советы по безопасности и производительности

Ограничение размера запроса

client_max_body_size 20M;

Разумные таймауты

proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

Сжатие Gzip

gzip on;
gzip_types text/plain application/json application/javascript text/css;
gzip_min_length 1000;

Rate limiting (базовая защита от DDoS)

limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m;

location /api/ {
    limit_req zone=api burst=10 nodelay;
    proxy_pass http://app1:3000;
}

Для профессионального управления сервером и углублённой настройки безопасности воспользуйтесь услугой администрирования серверов CLIQHOST.


Быстрое устранение неполадок

Проблема Решение
502 Bad Gateway Контейнер Docker не запущен или указан неверный порт
404 Not Found server_name не совпадает с запрашиваемым доменом
SSL_ERROR_RX_RECORD_TOO_LONG Nginx слушает 443, но блок SSL не настроен
Nginx не запускается Запустите sudo nginx -t для деталей ошибки

Проверьте логи Nginx:

sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log

Проверьте статус контейнеров:

docker ps
docker logs app1

Итог

Nginx как reverse proxy для Docker-контейнеров — мощная и гибкая связка: вы можете запускать десятки приложений на одном сервере, защищённых HTTPS, доступных через читаемые домены и изолированных друг от друга.

Для комфортной работы такой связки важны ресурсы сервера. Изучите планы VPS NVMe и управляемые выделенные серверы от CLIQHOST — надёжная инфраструктура в Молдове с профессиональной поддержкой.

Есть вопросы или нужна помощь с настройкой? Свяжитесь с командой CLIQHOST — мы готовы помочь.

SHARE
// Что говорят наши клиенты

Что говорят наши клиенты

Реальные отзывы клиентов, которые доверяют CLIQHOST за производительность, надёжность и профессиональную техническую поддержку.

★★★★★

"We moved our online shop from a foreign host and the difference is night and day — pages load instantly and support replies in minutes, in Romanian."

AM
Andrei M.
eCommerce owner · Chișinău
★★★★★

"Migrated 12 client sites to CLIQHOST. Free migration, zero downtime, and the cPanel setup is exactly what my team needed. Highly recommend."

EV
Elena V.
Web agency · Bălți
★★★★★

"Our NVMe VPS handles traffic spikes without a sweat. Full root, local datacenter, and billing in MDL — everything we wanted from a provider."

DC
Dmitri C.
SaaS founder · Chișinău