Работа с Docker на хостинге: от локального контейнера до продакшен-сервера
18 марта 2026 г.
Разработчик, который уверенно чувствует себя с Docker на локальной машине, рано или поздно сталкивается с задачей переноса контейнеров на удалённый сервер. Работа с Docker на хостинге открывает новые горизонты: изолированное окружение, лёгкое масштабирование и предсказуемый процесс деплоя. Однако эксплуатация контейнеров в продакшене требует понимания специфики: организации постоянного хранилища, сетевых настроек, безопасности и мониторинга.
1. Что такое Docker-хост и как выбрать сервер
Docker-хост — это сервер (физический или виртуальный), на котором запущен Docker Engine. В отличие от облачных платформ, предоставляющих Docker как услугу (например, AWS ECS), здесь вы полностью управляете инфраструктурой: от операционной системы до конфигурации демона.
Для работы подойдёт практически любой VPS или выделенный сервер, но есть ключевые требования:
- Операционная система: Linux (рекомендуются Ubuntu 22.04 LTS, Debian 12, CentOS Stream 9). Docker требует ядро версии 3.10 или новее, а также поддержку cgroups и namespaces.
- Ресурсы: сам Docker демон потребляет около 50-100 МБ RAM, но под каждый контейнер нужно закладывать ресурсы исходя из приложения. Для старта достаточно 1-2 ГБ RAM и 20-30 ГБ дискового пространства (SSD предпочтительнее).
- Архитектура: преимущественно x86_64, но Docker также работает на ARM (например, на серверах с процессорами Ampere).
- Доступ: root-доступ или пользователь с правами sudo по SSH. Без этого установка и настройка Docker невозможны.
При выборе хостинг-провайдера обращайте внимание на скорость дисков (важно для баз данных), качество канала и наличие регулярных бэкапов. Например, хостинг Timeweb предлагает гибкие тарифы с SSD-дисками. Если вам важна максимальная производительность, обратите внимание на хостинг Cloud4box — они предоставляют серверы на NVMe-дисках. При регистрации можно использовать промокод 3369_98051.
2. Подготовка сервера и установка Docker
2.1. Базовая настройка сервера
Перед установкой Docker приведите сервер в порядок. Это стандартные шаги для повышения безопасности и стабильности:
# Обновление пакетов
sudo apt update && sudo apt upgrade -y # для Ubuntu/Debian
# или
sudo dnf update -y # для CentOS/RHEL
# Установка базовых утилит
sudo apt install -y curl wget git htop # Ubuntu/Debian
# или
sudo dnf install -y curl wget git htop # CentOS/RHEL
# Настройка часового пояса (пример для Москвы)
sudo timedatectl set-timezone Europe/Moscow
# Создание отдельного пользователя (если работаете под root)
sudo adduser deployer
sudo usermod -aG sudo deployer
# Настройка SSH-ключей для нового пользователя (на локальной машине)
ssh-copy-id deployer@your-server-ipТакже рекомендуется настроить файрвол (UFW для Ubuntu или firewalld для CentOS) и разрешить только необходимые порты.
2.2. Установка Docker Engine
Самый надёжный способ установки Docker — через официальный репозиторий. Рассмотрим процесс для Ubuntu 22.04 LTS:
# Удаление старых версий (если были)
sudo apt remove docker docker-engine docker.io containerd runc
# Установка зависимостей
sudo apt install -y ca-certificates curl gnupg lsb-release
# Добавление официального GPG-ключа Docker
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Добавление репозитория
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Установка Docker Engine, CLI и Containerd
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
# Запуск Docker и добавление в автозагрузку
sudo systemctl start docker
sudo systemctl enable docker
# Проверка установки
sudo docker run hello-worldДля CentOS/RHEL процесс аналогичен — инструкции есть в официальной документации.
2.3. Установка Docker Compose
Docker Compose — незаменимый инструмент для оркестрации многоконтейнерных приложений. В современных версиях Docker Engine плагин compose входит в состав пакета docker-compose-plugin. Если вы устанавливали Docker через официальный репозиторий, плагин уже должен быть установлен. Проверьте:
docker compose versionЕсли команда не найдена, установите плагин отдельно:
sudo apt install -y docker-compose-pluginРекомендуется использовать именно плагин, так как он лучше интегрирован с основным CLI.
3. Настройка Docker для работы с обычным пользователем
По умолчанию для работы с Docker требуются права root. Чтобы разрешить вашему пользователю (например, deployer) запускать команды docker без sudo, добавьте его в группу docker:
sudo usermod -aG docker deployerПосле этого нужно выйти из сессии и зайти заново (или выполнить newgrp docker). Проверьте:
docker psЕсли команда отработала без ошибок, всё настроено правильно.
Важное предупреждение: группа docker даёт те же привилегии, что и root. Любой пользователь в этой группе может запускать контейнеры с монтированием любых папок хоста, что потенциально позволяет получить полный контроль над системой. Убедитесь, что в группе находятся только доверенные пользователи.
4. Основные операции с контейнерами на сервере
4.1. Проброс портов и сетевые взаимодействия
Когда вы запускаете контейнер на сервере, он изолирован от внешнего мира. Чтобы приложение стало доступно из интернета, нужно опубликовать (пробросить) порты контейнера на интерфейс хоста с помощью флага -p или --publish:
docker run -d --name myapp -p 80:80 nginxЭта команда пробрасывает порт 80 контейнера на порт 80 хоста. Теперь при обращении к IP-адресу сервера по HTTP вы попадёте в nginx внутри контейнера. Если на хосте уже есть процесс, занимающий порт 80, можно пробросить на другой порт, например -p 8080:80.
4.2. Управление данными: volumes и bind mounts
Контейнеры по умолчанию эфемерны — все данные, записанные внутри, пропадают при его удалении. Для продакшена это неприемлемо. Нужно использовать volumes или bind mounts.
Volumes — рекомендуемый способ хранения данных. Они полностью управляются Docker, хранятся в специальной директории на хосте (/var/lib/docker/volumes/) и легко бэкапятся.
# Создание volume
docker volume create pgdata
# Запуск контейнера с подключением volume
docker run -d --name postgres -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=secret postgres:13Bind mounts — привязка к конкретной папке на хосте. Удобно для конфигурационных файлов.
docker run -d --name nginx -v /home/deployer/nginx.conf:/etc/nginx/nginx.conf:ro -p 80:80 nginxФлаг :ro монтирует файл в режиме только для чтения — хорошая практика для конфигов.
4.3. Создание пользовательских сетей Docker
Для взаимодействия нескольких контейнеров (например, backend + база данных) лучше создать отдельную сеть. В пользовательской сети контейнеры могут обращаться друг к другу по именам.
# Создание сети
docker network create myapp-net
# Запуск контейнеров в этой сети
docker run -d --name postgres --network myapp-net -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=secret postgres:13
docker run -d --name backend --network myapp-net -p 3000:3000 mybackend:latestТеперь в контейнере backend вы можете подключиться к базе по имени хоста postgres.
5. Использование Docker Compose в продакшен-среде
5.1. Пример compose-файла для веб-приложения
Docker Compose позволяет описать всю инфраструктуру в декларативном YAML-файле. Допустим, у нас есть Node.js приложение с PostgreSQL и Redis:
version: '3.8'
services:
postgres:
image: postgres:15
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_USER: myuser
POSTGRES_PASSWORD: ${DB_PASSWORD}
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U myuser"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- backend
command: redis-server --appendonly yes
app:
build: .
restart: unless-stopped
ports:
- "3000:3000"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
environment:
DATABASE_URL: postgresql://myuser:${DB_PASSWORD}@postgres:5432/myapp
REDIS_URL: redis://redis:6379
networks:
- backend
- public
volumes:
- ./uploads:/app/uploads
volumes:
postgres_data:
redis_data:
networks:
backend:
internal: true
public:Обратите внимание на переменные окружения (берутся из файла .env), разделение сетей и использование healthcheck.
5.2. Деплой приложения с помощью Docker Compose
Скопируйте проект на сервер (через git или rsync) и выполните:
# Создайте файл .env с секретами
echo "DB_PASSWORD=supersecret" > .env
# Запустите все сервисы
docker compose up -d
# Посмотрите логи
docker compose logs -f
# Проверьте статус
docker compose ps5.3. Обновление сервисов без downtime
При изменении кода нужно обновить контейнер с приложением. Пересоберите образ и выполните:
docker compose up -d --buildCompose перезапустит только изменившиеся сервисы. Однако при этом может быть небольшая пауза. Для критичных сервисов потребуются более сложные стратегии (rolling update).
6. Организация хранения данных на продакшене
6.1. Стратегии бекапа для Docker volumes
Данные в volumes нужно регулярно бэкапить. Простой способ — использовать временный контейнер, который монтирует volume и архивирует его содержимое:
docker run --rm -v pgdata:/volume -v /backup:/backup alpine tar czf /backup/pgdata-$(date +%Y%m%d).tar.gz -C /volume .Для автоматизации добавьте задачу в cron. Например, создайте скрипт и добавьте запись в crontab:
0 2 * * * /usr/local/bin/backup-docker.sh6.2. Перенос volumes между серверами
Заархивируйте volume на старом сервере, скопируйте архив на новый и восстановите:
# На новом сервере создайте volume
docker volume create pgdata
# Распакуйте архив в volume
docker run --rm -v pgdata:/volume -v /path/to/backup:/backup alpine tar xzf /backup/pgdata-20240101.tar.gz -C /volume7. Автозапуск и мониторинг контейнеров
7.1. Политики рестарта
В продакшене контейнеры должны автоматически перезапускаться. Политика рестарта задаётся флагом --restart или директивой restart в compose. Для большинства сервисов оптимален режим unless-stopped.
7.2. Настройка логирования
Docker по умолчанию собирает stdout и stderr контейнеров. Настройте ротацию логов глобально через /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}После изменения файла перезапустите Docker: sudo systemctl restart docker.
7.3. Мониторинг ресурсов
Docker предоставляет встроенную команду docker stats. Для более серьёзного мониторинга используйте связку Prometheus + Grafana с Node Exporter и cAdvisor. Пример запуска cAdvisor:
docker run -d --name cadvisor -p 8080:8080 \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--volume=/dev/disk/:/dev/disk:ro \
gcr.io/cadvisor/cadvisor:latest8. Безопасность Docker в продакшене
8.1. Минимизация привилегий
В Dockerfile всегда создавайте отдельного пользователя и переключайтесь на него:
FROM node:18
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN chown -R appuser:appuser /app
USER appuser
CMD ["node", "server.js"]Если приложению нужны привилегии, используйте capability-флаги (--cap-drop=ALL --cap-add=NET_BIND_SERVICE) вместо полного root.
8.2. Безопасность образов и сканирование уязвимостей
Используйте только официальные образы и регулярно их обновляйте. Для сканирования на уязвимости используйте Trivy:
trivy image myapp:latest8.3. Ограничение ресурсов контейнеров
В docker-compose.yml можно ограничить ресурсы:
services:
app:
build: .
mem_limit: 512m
cpus: "0.5"8.4. Сетевая безопасность
- Не публикуйте порты сервисов, которые не должны быть доступны извне. Используйте внутренние сети (
internal: true). - Настройте файрвол на хосте.
- Используйте обратный прокси (Nginx, Traefik) с поддержкой HTTPS (Let's Encrypt).
При выборе провайдера для продакшена обратите внимание на компании, уделяющие внимание безопасности. Например, хостинг Eurobyte предлагает встроенную DDoS-защиту и регулярное резервное копирование. Если вам нужен бюджетный вариант, можно рассмотреть хостинг McHost.
9. Интеграция Docker с CI/CD-пайплайн
9.1. Автоматическая сборка и push образов
Пример workflow для GitHub Actions, который собирает образ и пушит его в Docker Hub при пуше в main:
name: Build and Push Docker Image
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: yourusername/myapp:latest9.2. Автоматический деплой на сервер
Добавьте шаг, который подключается к серверу по SSH и выполняет обновление:
- name: Deploy to server
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /path/to/project
docker compose pull
docker compose up -d10. Типичные ошибки при работе с Docker на хостинге
- Забытые volumes при обновлении. Всегда проверяйте, что volumes подключены.
- Конфликт портов. Используйте
sudo lsof -i :portдля диагностики. - Неверные права доступа к bind mounts. Либо меняйте права на хосте, либо запускайте контейнер с нужным пользователем.
- Игнорирование политик рестарта. Без
restart: unless-stoppedконтейнеры не запустятся после перезагрузки сервера. - Открытые порты базы данных. Никогда не публикуйте порт базы данных на внешний интерфейс.
- Неограниченные логи. Обязательно настраивайте ротацию.
11. Заключение
Работа с Docker на хостинге — это не просто перенос локального опыта на удалённую машину, а целый набор практик, обеспечивающих стабильность и безопасность. Мы разобрали ключевые аспекты: от выбора сервера до CI/CD. Начинайте с малого — разверните один проект с использованием Docker Compose. Постепенно внедряйте практики безопасности, настраивайте логи и мониторинг. Со временем вы выработаете шаблонный подход, который позволит разворачивать новые проекты за минуты.
Если вы только присматриваетесь к хостингам для Docker, обратите внимание на проверенных провайдеров: Timeweb с хорошей репутацией, Cloud4box с NVMe-дисками (промокод 3369_98051 даст скидку) или Eurobyte с усиленной защитой. Выбор зависит от ваших задач и бюджета.
Что почитать дальше
Дополнительные материалы из архива, которые могут быть полезны после этой статьи.
Полное руководство по CI/CD для Next.js в GitLab: от базовой настройки до продакшн-пайплайна
Подробное руководство по настройке CI/CD для Next.js приложений с GitLab CI. Разбираем каждый этап пайплайна, кэширован…
Читать далее
Production-деплой Next.js на VPS: пошаговое руководство
Научитесь деплоить Next.js приложение на VPS как профессионал: от настройки сервера и PM2 до запуска через Docker, наст…
Читать далее
Production-ready запуск React-приложения: от сборки до деплоя
Полное руководство по подготовке React-приложения к production: оптимизация сборки, настройка сервера, управление конфи…
Читать далее