Docker для сайтов: контейнеризация веб-приложений от А до Я

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Веб-разработчики, желающие освоить контейнеризацию с помощью Docker
  • Специалисты по DevOps, заинтересованные в оптимизации процессов разработки и деплоя
  • Студенты и новички в области программирования, стремящиеся изучить современные технологии веб-разработки

    Создание сайтов с использованием Docker — это не просто модный тренд, а технология, кардинально меняющая процессы разработки и деплоя веб-приложений. Разработчики, осваивающие контейнеризацию, получают решающее преимущество: сайт, работающий стабильно и идентично в любой среде — от локальной машины до промышленного сервера. Docker устраняет извечную проблему "у меня работает, а на проде нет", экономит время на настройке окружения и делает процесс масштабирования приложений предсказуемым. Пройдемся по всем этапам — от базовых принципов до готового к деплою контейнеризованного веб-сайта. 🚀

Хотите быстро освоить не только Docker, но и все ключевые технологии современной веб-разработки? Обучение веб-разработке от Skypro погружает вас в профессию через практику и реальные проекты. Наши выпускники умеют создавать контейнеризованные приложения, масштабируемые сервисы и быстро адаптируются к меняющимся требованиям индустрии. Станьте разработчиком, который решает бизнес-задачи, а не просто пишет код!

Основы контейнеризации для веб-разработки с Docker

Контейнеризация — это метод виртуализации на уровне операционной системы, позволяющий запускать приложения в изолированных средах (контейнерах). Docker реализует эту технологию, делая её доступной и удобной для разработчиков.

В отличие от виртуальных машин, контейнеры используют общее ядро операционной системы хоста, что делает их более легкими и эффективными. Они запускаются за миллисекунды и потребляют значительно меньше ресурсов.

Михаил Дронов, DevOps-инженер

Когда я присоединился к команде, разрабатывающей высоконагруженный новостной портал, первым делом столкнулся с проблемой: каждый разработчик настраивал окружение по-своему. Часто слышалось: "У меня всё работает, не понимаю, почему на тестовом сервере падает".

Внедрение Docker радикально изменило ситуацию. Мы создали единую конфигурацию в docker-compose.yml, описывающую весь стек: NGINX, PHP-FPM, MySQL, Redis и Elasticsearch. Теперь любой член команды или новый сотрудник мог запустить проект одной командой: docker-compose up.

Результат превзошел ожидания. Время на введение новых разработчиков в проект сократилось с недели до нескольких часов. Проблемы с "works on my machine" ушли в прошлое. А когда мы перешли на микросервисную архитектуру, Docker стал фундаментом, на котором мы построили всю инфраструктуру.

Основные компоненты экосистемы Docker:

  • Docker Engine — ядро системы, управляющее контейнерами
  • Docker Image — шаблон для создания контейнеров, содержащий код, библиотеки и зависимости
  • Docker Container — запущенный экземпляр образа, изолированная среда выполнения
  • Dockerfile — текстовый файл с инструкциями для сборки образа
  • Docker Compose — инструмент для определения и запуска многоконтейнерных приложений
  • Docker Hub — репозиторий для хранения и распространения образов

Для веб-разработки контейнеризация предлагает ряд существенных преимуществ:

Преимущество Описание Пример использования
Идентичность сред Устранение различий между локальной разработкой и продакшн-окружением Тестирование на локальной машине с уверенностью, что код будет работать так же в продакшне
Быстрая настройка Устранение "works on my machine" проблемы Новый разработчик начинает работу над проектом за минуты, а не дни
Изоляция сервисов Каждый компонент работает в собственном окружении Возможность использовать разные версии PHP для разных микросервисов
Масштабируемость Легкое горизонтальное масштабирование Запуск дополнительных контейнеров при повышенной нагрузке
Управление версиями Фиксация конкретных версий зависимостей Избежание проблем совместимости при обновлении библиотек
Пошаговый план для смены профессии

Настройка окружения: установка Docker и требования

Перед началом работы с Docker необходимо установить и настроить базовые компоненты на вашей системе. Требования различаются в зависимости от операционной системы. 🛠️

Системные требования для работы Docker:

  • Windows: Windows 10 64-bit (сборка 19041 или новее) с включенной функцией WSL 2 (Windows Subsystem for Linux)
  • macOS: macOS 10.14 (Mojave) или новее
  • Linux: Ядро версии 3.10 или новее, 64-разрядная система

Процесс установки Docker:

  1. Для Windows и macOS: Скачайте и установите Docker Desktop с официального сайта Docker.
  2. Для Linux (Ubuntu/Debian):
# Обновление пакетов
sudo apt-get update

# Установка необходимых пакетов для работы с HTTPS репозиториями
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release

# Добавление официального GPG-ключа Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Добавление стабильного репозитория Docker
echo "deb [arch=amd64 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 Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# Установка Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

После установки проверьте корректность работы Docker командами:

# Проверка версии Docker
docker --version

# Проверка версии Docker Compose
docker-compose --version

# Тестовый запуск контейнера
docker run hello-world

Если все команды выполняются без ошибок и вы видите приветственное сообщение от контейнера hello-world, ваша среда готова к работе с Docker.

Дополнительные настройки, улучшающие работу с Docker:

  • Добавьте вашего пользователя в группу docker, чтобы выполнять команды без sudo (для Linux):
sudo usermod -aG docker $USER

После этого требуется перезайти в систему

  • Настройте автозапуск Docker при старте системы:
sudo systemctl enable docker

  • Выделите достаточно ресурсов для Docker Desktop (Windows/macOS):
  • Рекомендуется минимум 4GB RAM
  • 2-4 CPU ядра
  • 20GB свободного места для образов

Сравнение производительности Docker на разных операционных системах:

Операционная система Особенности работы Docker Производительность Совместимость
Linux Нативная поддержка, прямой доступ к ядру Высокая Полная
macOS Работает через HyperKit, легковесный гипервизор Средняя Хорошая
Windows с WSL 2 Использует WSL 2 для запуска Linux-контейнеров Средняя Хорошая
Windows без WSL 2 Использует Hyper-V для виртуализации Низкая Ограниченная

Создание Dockerfile для компонентов вашего сайта

Dockerfile — это текстовый файл с инструкциями для создания образа Docker. Каждая строка в Dockerfile представляет собой слой в итоговом образе. Правильное создание Dockerfile критически важно для оптимизации размера образа, безопасности и производительности. 📝

Рассмотрим создание Dockerfile для типичных компонентов веб-сайта:

Веб-сервер (NGINX)

# Используем официальный образ NGINX
FROM nginx:1.23-alpine

# Копируем нашу конфигурацию
COPY ./config/nginx/site.conf /etc/nginx/conf.d/default.conf

# Копируем статические файлы
COPY ./public /var/www/html/public

# Настраиваем права доступа
RUN chown -R nginx:nginx /var/www/html

# Открываем порты
EXPOSE 80

# Запускаем NGINX в фоновом режиме
CMD ["nginx", "-g", "daemon off;"]

PHP-приложение

# Используем официальный образ PHP-FPM
FROM php:8.1-fpm-alpine

# Устанавливаем необходимые расширения PHP
RUN apk add --no-cache $PHPIZE_DEPS \
&& docker-php-ext-install pdo_mysql mysqli opcache \
&& pecl install redis \
&& docker-php-ext-enable redis

# Оптимизируем конфигурацию PHP для продакшена
COPY ./config/php/php.ini /usr/local/etc/php/conf.d/php-custom.ini

# Копируем код приложения
COPY ./src /var/www/html

# Устанавливаем Composer и зависимости
COPY --from=composer:2.4 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
RUN composer install --no-dev --optimize-autoloader

# Устанавливаем правильные права
RUN chown -R www-data:www-data /var/www/html

# Запускаем PHP-FPM
CMD ["php-fpm"]

База данных (MySQL)

# Используем официальный образ MySQL
FROM mysql:8.0

# Копируем скрипты инициализации
COPY ./database/init.sql /docker-entrypoint-initdb.d/

# Настраиваем конфигурацию MySQL
COPY ./config/mysql/my.cnf /etc/mysql/conf.d/custom.cnf

# Контрольная точка для проверки готовности сервера
HEALTHCHECK --interval=5s --timeout=3s --retries=3 CMD mysqladmin ping -h localhost -u root -p"${MYSQL_ROOT_PASSWORD}" || exit 1

# Данные хранятся во внешнем томе, монтируемом через docker-compose
VOLUME /var/lib/mysql

Ключевые принципы оптимизации Dockerfile:

  • Многоступенчатая сборка — для уменьшения размера итогового образа
  • Минимальные базовые образы — предпочтение Alpine-версиям образов
  • Группировка команд RUN — для уменьшения количества слоев
  • Удаление ненужных файлов — после завершения установки зависимостей
  • Использование .dockerignore — для исключения ненужных файлов из контекста сборки
  • Явное указание версий — вместо тегов latest для предсказуемости

Алексей Воронцов, Full Stack разработчик

В прошлом году мы с командой переводили на Docker крупный интернет-магазин с миллионами посещений в месяц. Сайт работал на "зоопарке" технологий: PHP-бэкенд, Node.js для обработки платежей, Python для аналитики и рекомендаций.

Первая проблема возникла при создании Dockerfile для PHP-части. Мы сделали всё "по книжке" — установили все расширения, скопировали код и запустили. Образ вышел огромным — почти 2 ГБ! При масштабировании это создавало серьезные задержки.

Ключевым решением стала многоступенчатая сборка. В первом этапе мы устанавливали все инструменты для компиляции и зависимости Composer, во втором — только копировали готовый код и минимальный набор расширений. Размер образа уменьшился до 180 МБ.

Еще один урок мы извлекли, забыв добавить файл .dockerignore. При каждом билде Docker отправлял в контекст сборки гигабайты данных из папок node_modules и vendor. Добавление .dockerignore сократило время сборки с 15 минут до 30 секунд.

После оптимизации всех Dockerfile деплой стал занимать не 25-30 минут, как раньше, а всего 2-3 минуты, что позволило нам внедрить CI/CD и доставлять новые функции значительно быстрее.

Пример файла .dockerignore для типичного веб-проекта:

# Системные файлы
.git
.gitignore
.env
.DS_Store

# Зависимости
node_modules
vendor
**/node_modules
**/vendor

# Кеши и логи
var/cache/*
var/log/*
*.log
npm-debug.log

# Инструменты разработки
Dockerfile*
docker-compose*
.dockerignore
README.md
phpunit.xml
tests/
docs/

Организация структуры проекта с docker-compose

Docker Compose — это инструмент для определения и запуска многоконтейнерных приложений. С его помощью вы можете описать всю инфраструктуру вашего сайта в одном YAML-файле и запустить её одной командой. 🔄

Типичная структура проекта с использованием Docker Compose:

project-root/
├── docker-compose.yml # Основной файл конфигурации
├── docker-compose.override.yml # Переопределения для локальной разработки
├── .env # Переменные окружения для docker-compose
├── docker/ # Папка с Dockerfile и конфигурациями
│ ├── nginx/
│ │ ├── Dockerfile
│ │ └── config/
│ ├── php/
│ │ ├── Dockerfile
│ │ └── config/
│ └── mysql/
│ ├── Dockerfile
│ └── config/
├── src/ # Исходный код приложения
└── public/ # Публичные файлы

Пример комплексного файла docker-compose.yml для типичного веб-проекта:

version: '3.8'

services:
nginx:
build:
context: ./docker/nginx
ports:
- "80:80"
volumes:
- ./public:/var/www/html/public:ro
depends_on:
- php
networks:
- frontend
restart: unless-stopped

php:
build:
context: ./docker/php
volumes:
- ./src:/var/www/html:rw
- ./docker/php/config/php.ini:/usr/local/etc/php/conf.d/php-custom.ini:ro
depends_on:
- mysql
- redis
networks:
- frontend
- backend
restart: unless-stopped
env_file:
- .env

mysql:
build:
context: ./docker/mysql
volumes:
- mysql_data:/var/lib/mysql
networks:
- backend
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}

redis:
image: redis:6-alpine
volumes:
- redis_data:/data
networks:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 3

networks:
frontend:
backend:

volumes:
mysql_data:
redis_data:

Ключевые секции и концепции docker-compose.yml:

  • services — определяет контейнеры, которые составляют ваше приложение
  • networks — изолированные сети для коммуникации между контейнерами
  • volumes — постоянные хранилища данных, не удаляемые при перезапуске контейнеров
  • depends_on — определяет зависимости между сервисами для правильного порядка запуска
  • env_file — подключает файл с переменными окружения
  • restart — политика перезапуска контейнеров при сбоях

Для разделения конфигураций между разработкой и продакшеном рекомендуется использовать несколько файлов docker-compose:

# docker-compose.yml – базовая конфигурация
# docker-compose.override.yml – автоматически подключается, используется для разработки
# docker-compose.prod.yml – конфигурация для продакшена

# Запуск в режиме разработки (используется override автоматически):
docker-compose up -d

# Запуск для продакшена:
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Пример docker-compose.override.yml для разработки:

version: '3.8'

services:
nginx:
ports:
- "8080:80" # Другой порт для избежания конфликтов
volumes:
- ./docker/nginx/config/site.dev.conf:/etc/nginx/conf.d/default.conf:ro

php:
build:
args:
- WITH_XDEBUG=true
volumes:
- ./docker/php/config/php-dev.ini:/usr/local/etc/php/conf.d/php-custom.ini:ro
environment:
- PHP_IDE_CONFIG=serverName=docker
- XDEBUG_MODE=debug
- XDEBUG_CONFIG=client_host=host.docker.internal client_port=9003

mysql:
ports:
- "3306:3306" # Открываем порт для подключения из IDE

adminer: # Дополнительный сервис только для разработки
image: adminer
restart: always
ports:
- "8888:8080"
depends_on:
- mysql
networks:
- backend

Пример docker-compose.prod.yml для продакшена:

version: '3.8'

services:
nginx:
image: ${REGISTRY}/project-nginx:${TAG}
deploy:
replicas: 2
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

php:
image: ${REGISTRY}/project-php:${TAG}
deploy:
replicas: 4
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

mysql:
volumes:
- ./docker/mysql/config/my-prod.cnf:/etc/mysql/conf.d/custom.cnf:ro
deploy:
resources:
limits:
cpus: '2'
memory: 4G

Развертывание и управление сайтом в контейнерах

После подготовки всех необходимых конфигураций наступает этап развертывания и управления контейнеризированным веб-сайтом. Этот процесс включает в себя запуск контейнеров, мониторинг их состояния и выполнение операций обслуживания. 🚢

Основные команды для управления контейнерами:

# Запуск всех сервисов в фоновом режиме
docker-compose up -d

# Проверка статуса запущенных контейнеров
docker-compose ps

# Просмотр логов
docker-compose logs -f [service_name]

# Остановка всех контейнеров без удаления
docker-compose stop

# Остановка и удаление контейнеров
docker-compose down

# Перезапуск отдельного сервиса
docker-compose restart [service_name]

# Выполнение команды внутри запущенного контейнера
docker-compose exec [service_name] [command]

Для непрерывной интеграции и доставки (CI/CD) с Docker рекомендуется следующий пайплайн:

  1. Сборка и тестирование образов при каждом коммите
  2. Автоматическая публикация образов в приватный Docker Registry
  3. Развертывание в тестовое окружение для QA
  4. Развертывание в продакшн после одобрения

Пример скрипта для CI/CD в GitLab:

stages:
- build
- test
- publish
- deploy

variables:
REGISTRY: registry.example.com
TAG: $CI_COMMIT_SHORT_SHA

build:
stage: build
script:
- docker-compose -f docker-compose.yml build
- docker tag myproject-nginx:latest $REGISTRY/myproject-nginx:$TAG
- docker tag myproject-php:latest $REGISTRY/myproject-php:$TAG

test:
stage: test
script:
- docker-compose -f docker-compose.yml -f docker-compose.test.yml up -d
- docker-compose exec php vendor/bin/phpunit
- docker-compose down

publish:
stage: publish
script:
- docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD $REGISTRY
- docker push $REGISTRY/myproject-nginx:$TAG
- docker push $REGISTRY/myproject-php:$TAG

deploy_staging:
stage: deploy
script:
- ssh deploy@staging.example.com "cd /opt/myproject && export TAG=$TAG && docker-compose -f docker-compose.yml -f docker-compose.staging.yml pull && docker-compose -f docker-compose.yml -f docker-compose.staging.yml up -d"

deploy_production:
stage: deploy
when: manual
script:
- ssh deploy@prod.example.com "cd /opt/myproject && export TAG=$TAG && docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull && docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d"

Мониторинг и обслуживание Docker-контейнеров в продакшене:

Инструмент Описание Применение
Prometheus Система мониторинга и оповещения Сбор метрик о производительности контейнеров и хостов
Grafana Платформа для визуализации данных Создание информативных дашбордов на основе метрик Prometheus
cAdvisor Анализатор ресурсов и производительности контейнеров Детальный мониторинг использования ресурсов каждым контейнером
Portainer Графический интерфейс для управления Docker Упрощенное управление контейнерами, сетями и томами через веб-интерфейс
Watchtower Автоматическое обновление контейнеров Отслеживание новых версий образов и автоматическое обновление контейнеров

Резервное копирование и восстановление данных:

  1. Резервное копирование томов:
docker run --rm -v myproject_mysql_data:/source -v $(pwd)/backups:/backup alpine tar -czf /backup/mysql-backup-$(date +%Y%m%d).tar.gz -C /source .

  1. Восстановление данных:
docker run --rm -v myproject_mysql_data:/target -v $(pwd)/backups:/backup alpine sh -c "rm -rf /target/* && tar -xzf /backup/mysql-backup-20221010.tar.gz -C /target"

  1. Дамп базы данных:
docker-compose exec mysql mysqldump -u root -p --all-databases > backups/full-dump-$(date +%Y%m%d).sql

Рекомендации по оптимизации производительности контейнеров в продакшене:

  • Используйте ограничения ресурсов (cpulimit, memorylimit) для каждого контейнера
  • Настройте healthcheck для отслеживания работоспособности сервисов
  • Применяйте restart_policy для автоматического восстановления после сбоев
  • Используйте сети типа overlay для межхостовой коммуникации в кластере
  • Применяйте Docker Swarm или Kubernetes для оркестрации контейнеров в больших инсталляциях
  • Регулярно обновляйте базовые образы для получения исправлений безопасности
  • Используйте многоэтапную сборку для минимизации размера финальных образов

Масштабирование веб-приложения:

# Горизонтальное масштабирование сервиса php до 5 реплик
docker-compose up -d --scale php=5

# При использовании Docker Swarm:
docker service update --replicas 5 mystack_php

Docker превратил процесс развертывания веб-сайтов из сложной головоломки в предсказуемый и надежный процесс. Контейнеризация не только упрощает работу команды разработки, но и радикально меняет подход к масштабированию и поддержке приложений. Освоив принципы, описанные в этом руководстве, вы сможете создавать надежные, масштабируемые и повторяемые инфраструктуры для сайтов любой сложности. Технология не стоит на месте — Docker становится стандартом индустрии, который нельзя игнорировать современному веб-разработчику.

Загрузка...