Содержание

Docker упаковывает приложение вместе со всем окружением — версией языка, библиотеками, настройками — в контейнер, который одинаково запускается на ноутбуке разработчика, в CI и на продакшен-сервере. Для проекта это означает быстрый старт новых разработчиков, предсказуемые выкладки без «у меня работало» и простой переезд между серверами и облаками.

Разберём, что даёт Docker, как устроить его для разработки и продакшена и где он не нужен.

Какие проблемы решает Docker?

Docker решает проблему различий окружений: версия PHP, Node.js или Python, системные библиотеки и настройки на сервере отличаются от тех, что у разработчика, и код, который работал локально, ломается при выкладке. Контейнер фиксирует окружение в коде, и оно становится одинаковым везде.

Что получает проект:

  • быстрый старт — новый разработчик запускает проект одной командой, а не собирает окружение день;
  • одинаковые окружения — разработка, тесты и продакшен работают на одном образе;
  • предсказуемые выкладки — на сервер уходит проверенный образ, а не набор файлов;
  • простой откат — вернуться на предыдущую версию значит запустить предыдущий образ;
  • переносимость — контейнеры запускаются на любом сервере и в любом облаке.

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

Как устроен Docker-проект?

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

# Сборка зависимостей отдельно — финальный образ меньше и безопаснее
FROM composer:2 AS vendor
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --prefer-dist

FROM php:8.4-fpm-alpine
WORKDIR /var/www/app
RUN docker-php-ext-install pdo_pgsql opcache
COPY --from=vendor /app/vendor ./vendor
COPY . .
USER www-data
# compose.yaml — всё окружение разработки одной командой
services:
  app:
    build: .
    volumes: ['.:/var/www/app']
    depends_on: [postgres, redis]
  postgres:
    image: postgres:18
    environment: { POSTGRES_PASSWORD: secret }
  redis:
    image: redis:8-alpine

Синие контейнеры, выстроенные в ряд Фото: Unsplash

Чем Docker для разработки отличается от продакшена?

Docker для разработки оптимизирован под удобство — код монтируется с диска, работает отладка, включены инструменты разработчика, — а для продакшена под надёжность и безопасность: минимальный образ, код внутри образа, никаких лишних инструментов и запуск не от root.

Аспект Разработка Продакшен
Код Монтируется с диска, изменения видны сразу Копируется в образ при сборке
Зависимости Включая инструменты разработки Только необходимые для работы
Отладка Включена Выключена
Пользователь Удобный для работы с файлами Непривилегированный, не root
Секреты Тестовые значения в .env Из хранилища секретов или переменных окружения сервера
База данных В контейнере рядом Часто управляемый облачный сервис

Правила для продакшен-образов

  1. Многоступенчатая сборка — инструменты сборки не попадают в финальный образ.
  2. Фиксированные версии базовых образов, а не latest.
  3. Регулярная пересборка с обновлёнными базовыми образами — в них выходят исправления безопасности.
  4. Секреты не записываются в образ.
  5. Проверка образов на уязвимости в CI.

Где запускать контейнеры в продакшене?

Запускать контейнеры можно на обычном сервере через Docker Compose, в управляемых облачных сервисах для контейнеров или в Kubernetes. Для большинства небольших и средних проектов достаточно первых двух вариантов.

Как выбрать:

  • один-два сервера и Docker Compose — просто, дёшево, достаточно для многих проектов;
  • управляемые контейнерные сервисы облака — масштабирование и перезапуск без своей оркестрации;
  • Kubernetes — когда сервисов много, нужна автоматическая масштабируемость и есть команда для эксплуатации.

База данных в продакшене часто живёт вне контейнеров — в управляемом облачном сервисе с бэкапами и репликами. Архитектурный выбор между монолитом и сервисами влияет и на то, сколько контейнеров понадобится, — об этом в статье монолит или микросервисы.

Когда Docker не нужен?

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

Но для любого проекта, который будут развивать несколько человек или переносить между серверами, Docker почти всегда окупается уже в первые месяцы.

Коротко

  • Docker упаковывает приложение с окружением и делает разработку, тесты и продакшен одинаковыми.
  • Dockerfile описывает образ, Docker Compose — набор сервисов проекта.
  • Для разработки важно удобство, для продакшена — минимальный образ, безопасность и фиксированные версии.
  • Для большинства проектов хватает Docker Compose или управляемых облачных сервисов; Kubernetes — для многих сервисов.
  • Docker окупается в любом проекте, над которым работают несколько человек.

Частые вопросы

  • Можно ли запускать базу данных в Docker на продакшене?

    Можно, если данные хранятся в постоянном томе, а бэкапы и мониторинг настроены. Но для многих проектов проще и надёжнее управляемая облачная база с автоматическими бэкапами и репликами.

  • Замедляет ли Docker работу приложения?

    На Linux-серверах накладные расходы контейнеров минимальны. На macOS и Windows при разработке файловые операции в смонтированных папках могут быть медленнее — это решается настройками монтирования.

  • Чем Docker отличается от виртуальной машины?

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