Когда проект разрастается, настройка окружения превращается в настоящий квест. На одном сервере стоит PHP 7.4, на другом — 8.1, у одного разработчика — Windows, у другого — Mac, а в продакшене — свой Linux со своими нюансами. Знакомая ситуация?
Docker решает эту проблему, упаковывая приложение со всеми его зависимостями в изолированный контейнер, который работает одинаково на любой системе. Это позволяет разработчикам забыть о фразе «на моей машине работает», автоматизировать развёртывание и легко масштабировать инфраструктуру.
В этой статье мы разберём:
- Что такое контейнеризация и чем Docker отличается от виртуальных машин.
- Установку Docker и Docker Compose на разных ОС.
- Основные команды для работы с контейнерами и образами.
- Создание собственных образов через Dockerfile.
- Организацию многоконтейнерных приложений с Docker Compose.
- Практические примеры: запуск LEMP-стека и приложения на Node.js.
- Автоматизацию развёртывания и лучшие практики.
1. Что такое Docker и зачем он нужен
Docker — это платформа для разработки, доставки и запуска приложений в контейнерах. Контейнер — это лёгкая, изолированная среда, которая содержит всё необходимое для работы приложения: код, библиотеки, системные зависимости, переменные окружения.
Контейнеры vs виртуальные машины
Главное отличие — контейнеры используют ядро хост-системы, а виртуальные машины эмулируют полноценное аппаратное обеспечение с собственной ОС.
| Характеристика | Контейнеры (Docker) | Виртуальные машины |
|---|---|---|
| Запуск | Мгновенный | От секунд до минут |
| Ресурсы | Занимают минимум памяти | Требуют много памяти и диска |
| Изоляция | На уровне процессов | Полная аппаратная изоляция |
| Переносимость | Высокая | Ограничена гипервизором |
| Время развёртывания | Секунды | Минуты |
Преимущества Docker:
- Единообразие окружений — приложение работает одинаково на всех этапах (разработка, тестирование, продакшен).
- Изоляция — контейнеры не влияют друг на друга.
- Лёгкость масштабирования — можно запускать десятки экземпляров одного сервиса.
- Версионирование — образы можно сохранять, тегировать и откатывать.
- Упрощение деплоя — не нужно вручную настраивать сервер, достаточно запустить контейнер.
2. Установка Docker и Docker Compose
2.1 Установка Docker на Ubuntu / Debian
# Обновление пакетов и установка зависимостей
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
# Добавление официального GPG-ключа
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Добавление репозитория
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Установка Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
# Добавление пользователя в группу docker (чтобы не использовать sudo)
sudo usermod -aG docker $USER
# Запуск и автозагрузка
sudo systemctl start docker
sudo systemctl enable dockerПосле добавления пользователя в группу необходимо выйти из системы и зайти заново.
2.2 Установка Docker на CentOS / RHEL / Rocky Linux
# Установка зависимостей
sudo dnf install -y yum-utils
# Добавление репозитория
sudo yum-config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
# Установка Docker
sudo dnf install docker-ce docker-ce-cli containerd.io
# Добавление пользователя в группу
sudo usermod -aG docker $USER
# Запуск и автозагрузка
sudo systemctl start docker
sudo systemctl enable docker2.3 Установка Docker на Windows
- Скачайте и установите Docker Desktop с официального сайта.
- Убедитесь, что в BIOS включена виртуализация (Hyper-V или WSL2).
- После установки перезагрузите систему.
- В настройках Docker Desktop выберите использование WSL2 для лучшей производительности.
После установки Docker Desktop стоит проверить в настройках (Settings → Resources → WSL Integration), правильно ли настроена интеграция с WSL2 — это сильно влияет на производительность при работе с файловой системой.
2.4 Установка Docker Compose
Docker Compose — это инструмент для запуска многоконтейнерных приложений. Обычно он устанавливается отдельно.
# Скачивание последней версии
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Права на выполнение
sudo chmod +x /usr/local/bin/docker-compose
# Проверка версии
docker-compose --versionВ новых версиях Docker Compose интегрирован в команду docker compose (без дефиса). Если у вас установлен Docker Desktop, он уже идёт в комплекте.
3. Основы работы с Docker
3.1 Образы (Images) и контейнеры (Containers)
- Образ — это шаблон, содержащий всё необходимое для запуска приложения (ОС, зависимости, код). Образы неизменяемы.
- Контейнер — запущенный экземпляр образа. Он может быть изменён, но изменения не сохраняются в образе.
3.2 Основные команды Docker
Работа с образами:
# Поиск образа в Docker Hub
docker search nginx
# Скачивание образа
docker pull nginx:latest
# Список локальных образов
docker images
# Удаление образа
docker rmi nginx:latestРабота с контейнерами:
# Запуск контейнера из образа
docker run -d --name mynginx -p 8080:80 nginx
# Список запущенных контейнеров
docker ps
# Список всех контейнеров (включая остановленные)
docker ps -a
# Остановка контейнера
docker stop mynginx
# Запуск остановленного контейнера
docker start mynginx
# Удаление контейнера
docker rm mynginx
# Выполнение команды внутри контейнера
docker exec -it mynginx bash
# Просмотр логов
docker logs mynginx
# Просмотр статистики использования ресурсов
docker statsКлючи команды docker run:
| Ключ | Описание |
|---|---|
-d | Запуск в фоновом режиме (detach) |
--name | Указание имени контейнера |
-p | Проброс портов (хост:контейнер) |
-v | Монтирование томов (хост:контейнер) |
-e | Установка переменной окружения |
--restart | Политика перезапуска (always, on-failure) |
-it | Интерактивный режим с терминалом |
3.3 Работа с томами (Volumes)
По умолчанию данные внутри контейнера не сохраняются после его удаления. Чтобы этого избежать, используют тома.
Три способа монтирования данных:
1. Базовое монтирование директории (bind mount):
docker run -d -p 8080:80 -v /путь/на/хосте:/usr/share/nginx/html nginx2. Именованный том (volume):
# Создание тома
docker volume create mydata
# Использование тома
docker run -d -v mydata:/data alpine3. Временное хранилище (tmpfs) — только в памяти:
docker run -d --tmpfs /tmp alpine4. Создание собственных образов с Dockerfile
Dockerfile — это текстовый файл с инструкциями по сборке образа.
4.1 Структура Dockerfile
Рассмотрим простой пример для PHP-приложения:
# Базовый образ (используем официальный PHP с Apache)
FROM php:8.1-apache
# Копирование файлов проекта в контейнер
COPY . /var/www/html/
# Установка PHP-расширений
RUN docker-php-ext-install mysqli pdo pdo_mysql
# Включение модуля Apache
RUN a2enmod rewrite
# Настройка рабочей директории
WORKDIR /var/www/html
# Открываем порт
EXPOSE 80
# Команда по умолчанию (запуск Apache)
CMD ["apache2-foreground"]
4.2 Основные инструкции Dockerfile
| Инструкция | Описание |
|---|---|
FROM | Базовый образ |
RUN | Выполнение команды во время сборки |
COPY | Копирование файлов с хоста в контейнер |
ADD | Аналог COPY, но умеет распаковывать архивы |
WORKDIR | Установка рабочей директории |
ENV | Установка переменных окружения |
ARG | Переменная времени сборки |
EXPOSE | Документирование портов |
CMD | Команда по умолчанию при запуске |
ENTRYPOINT | Основная команда для запуска контейнера |
VOLUME | Монтирование тома |
4.3 Сборка и запуск образа
# Сборка образа
docker build -t my-php-app .
# Запуск контейнера из собранного образа
docker run -d -p 8080:80 --name myapp my-php-app4.4 Оптимизация Dockerfile
Советы по сборке эффективных образов:
- Используйте многоступенчатую сборку (multi-stage) для уменьшения размера.
- Объединяйте команды
RUNв одну строку (чтобы уменьшить количество слоёв). - Копируйте файлы в конце — это ускорит повторную сборку при изменении кода.
- Используйте .dockerignore, чтобы исключить ненужные файлы.
- Если часто меняется код приложения, но базовые зависимости (например, базовый образ ОС) остаются теми же, Docker будет эффективно использовать уже собранные слои — это ускорит повторные сборки.
Пример с многоступенчатой сборкой для Node.js:
# Этап сборки
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Этап исполнения
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
5. Docker Compose для многоконтейнерных приложений
Docker Compose позволяет описывать все сервисы приложения в одном файле docker-compose.yml и запускать их одной командой.
5.1 Базовая структура docker-compose.yml
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
restart: always
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
volumes:
- db_data:/var/lib/mysql
restart: always
volumes:
db_data:5.2 Основные команды Docker Compose
# Запуск всех сервисов (в фоне)
docker-compose up -d
# Остановка и удаление контейнеров
docker-compose down
# Просмотр логов
docker-compose logs -f
# Пересборка и запуск
docker-compose up -d --build
# Масштабирование сервиса
docker-compose up -d --scale web=3
# Выполнение команды в контейнере
docker-compose exec web bash5.3 Пример: LEMP-стек (Linux, Nginx, MySQL, PHP)
services:
db:
image: mariadb:10.6
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 2s
retries: 5
php:
depends_on:
db:
condition: service_healthy
restart: always
volumes:
db_data:Никогда не храните пароли в docker-compose.yml в репозитории. Используйте .env и добавьте его в .gitignore.
5.4 Пример: Node.js + Redis
services:
app:
build: .
ports:
- "3000:3000"
environment:
- REDIS_URL=redis://redis:6379
depends_on:
- redis
restart: always
redis:
image: redis:alpine
restart: alwaysВ нашем каталоге шаблонов docker-compose вы найдёте примеры с .env, healthcheck и безопасными настройками — их можно быстро адаптировать под свой проект.
6. Автоматизация развёртывания
6.1 Использование Docker в CI/CD
Контейнеры идеально вписываются в пайплайны непрерывной интеграции и доставки.
Типичный сценарий:
- Разработчик пушит код в репозиторий.
- CI-система (например, GitHub Actions или GitLab CI) собирает Docker-образ.
- Образ тестируется в контейнере (запуск тестов, линтеров).
- Готовый образ отправляется в реестр (Docker Hub, приватный реестр).
- На сервере новый образ развёртывается автоматически.
Пример GitHub Actions для сборки и публикации образа:
name: Build and Push Docker Image
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v4
with:
push: true
tags: myuser/myapp:latestЭти значения хранятся в настройках репозитория (Settings → Secrets → Actions) и никогда не должны попадать в код. Не копируйте эти значения в репозиторий. Переменные DOCKER_USERNAME и DOCKER_PASSWORD берутся из секретов GitHub (Settings → Secrets → Actions)
6.2 Развёртывание на сервере
На продакшен-сервере достаточно иметь установленные Docker и Docker Compose.
Самый простой способ деплоя:
# Копирование кода и docker-compose.yml на сервер
rsync -avz --exclude='node_modules' ./ user@server:/app/
# Запуск обновлённой версии
cd /app
docker-compose down
docker-compose pull
docker-compose up -dМожно автоматизировать этот процесс с помощью простого скрипта:
#!/usr/bin/env bash
set -euo pipefail
echo "Начинаем деплой..."
git pull origin main
echo "Контейнеры остановлены."
docker-compose down
echo "Образы собраны."
docker-compose build --pull
echo "Сервисы запущены."
docker-compose up -d
echo "✅ Деплой успешно завершён!"6.3 Использование Docker Swarm или Kubernetes
Для крупных проектов с десятками серверов используют оркестраторы:
- Docker Swarm — встроенный в Docker инструмент для кластеризации.
- Kubernetes — мощная, но сложная система от Google, ставшая стандартом в индустрии.
Для небольших и средних проектов Docker Swarm может быть хорошим выбором благодаря своей простоте.
# Инициализация кластера Swarm
docker swarm init
# Развёртывание стека только для кластера!!!
docker stack deploy -c docker-compose.yml myapp
# Управление сервисами
docker service ls
docker service scale myapp_web=5🔍 Важно: Команда docker stack deploy предназначена для кластеров Docker Swarm и не является заменой обычного docker-compose up. Для одиночного сервера используйте docker compose up -d.
7. Практические советы и лучшие практики
7.1 Безопасность Docker
- Не запускайте контейнеры от root — используйте пользователя с ограниченными правами.
- Регулярно обновляйте образы — старые версии могут содержать уязвимости.
- Не храните секреты в образах — используйте переменные окружения или секреты (Docker Secrets).
- Ограничивайте ресурсы контейнеров (CPU и память) с помощью
--cpusи--memory. - Сканируйте образы на уязвимости (например, Docker Scout или Trivy).
7.2 Оптимизация и управление ресурсами
# Ограничение памяти и CPU при запуске
docker run -d --memory=256m --cpus=0.5 nginx
# Очистка неиспользуемых объектов Docker
docker system prune -af
# Очистка всех томов, образов и контейнеров
docker system prune -a --volumes⚠️ Осторожно: Команды docker system prune -a --volumes удаляют все неиспользуемые объекты, включая тома с данными. Не используйте их на продакшене без полного понимания последствий.
7.3 Логирование
По умолчанию Docker записывает всё в stdout/stderr. Для продакшена стоит настроить драйвер логов:
# В docker-compose.yml
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"7.4 Когда НЕ стоит использовать Docker
- Очень маленькие проекты — настройка Docker может быть избыточной.
- Приложения с высокими требованиями к производительности — особенно если критична задержка при работе с железом.
- Специфическое ПО — иногда проще установить напрямую на хост.
8. Заключение
Docker — это мощный и гибкий инструмент, который позволяет:
- Упаковывать приложения в изолированные и переносимые контейнеры.
- Описывать всю инфраструктуру кодом (Infrastructure as Code).
- Легко масштабировать и автоматизировать развёртывание.
Мы рассмотрели ключевые концепции, установку, базовые команды, создание образов, многоконтейнерные приложения и автоматизацию. Практические примеры показывают, как можно использовать Docker для организации реальных проектов.
Освоив контейнеризацию, вы перейдёте на новый уровень разработки и администрирования. Ваши проекты станут более надёжными, предсказуемыми и легко масштабируемыми.
На codestack.space собраны не только статьи, но и полезные инструменты для веб‑разработчиков и администраторов: конструкторы конфигураций, шаблоны Dockerfile, сниппеты для CI/CD и чек‑листы по безопасности — чтобы сложные вещи можно было быстро развернуть и адаптировать под свой сервер
