Антон Ларичев

Введение
Docker давно стал стандартом де-факто для разработки, тестирования и развёртывания приложений. Если вы только начинаете путь в веб-разработке или бэкенде, рано или поздно столкнётесь с фразой "просто задеплой это в докере". В этой статье разберём, что такое Docker, зачем он нужен и как написать свой первый Dockerfile без лишней магии.
Что такое Docker и зачем он нужен разработчику
Docker — это платформа для упаковки приложения вместе со всеми его зависимостями в изолированный контейнер. Контейнер гарантирует, что приложение будет работать одинаково на ноутбуке разработчика, на сервере тестирования и в продакшене.
Главные проблемы, которые решает Docker:
- "У меня локально работает" — контейнер включает все зависимости, версии библиотек и настройки окружения.
- Долгая настройка окружения для новых разработчиков — вместо инструкции на две страницы достаточно одной команды.
- Конфликты версий — можно одновременно запускать проекты с разными версиями Node.js, PostgreSQL или Python без конфликтов на одной машине.
Установка Docker
Для начала работы установите Docker Desktop (Windows, macOS) или Docker Engine (Linux). После установки проверьте, что всё работает:
docker --version
docker run hello-world
Если вторая команда вывела приветственное сообщение, значит Docker установлен и настроен верно.
Ключевые понятия: образы и контейнеры
Docker образ (image)
Образ — это неизменяемый шаблон, который содержит код приложения, зависимости и инструкции для запуска. Образы хранятся в реестрах, например Docker Hub.
Docker контейнер
Контейнер — это запущенный экземпляр образа. Из одного образа можно запустить сколько угодно контейнеров, и каждый будет изолирован от остальных.
# скачать образ node версии 20
docker pull node:20
# запустить контейнер и зайти в его консоль
docker run -it node:20 bash
Пишем свой первый Dockerfile
Dockerfile — это текстовый файл с инструкциями по сборке образа. Рассмотрим пример для простого Node.js приложения.
# базовый образ с нужной версией node
FROM node:20-alpine
# рабочая директория внутри контейнера
WORKDIR /app
# сначала копируем только файлы зависимостей для кеширования слоёв
COPY package*.json ./
# устанавливаем зависимости
RUN npm ci --production
# копируем остальной код приложения
COPY . .
# порт, который слушает приложение
EXPOSE 3000
# команда запуска
CMD ["node", "index.js"]
Соберите образ и запустите контейнер:
docker build -t my-app:1.0 .
docker run -p 3000:3000 my-app:1.0
Флаг -p 3000:3000 пробрасывает порт контейнера на порт хост-машины, а -t задаёт имя и тег образа.
Docker Compose для многоконтейнерных приложений
Реальные приложения редко состоят из одного контейнера — обычно нужны ещё база данных, кеш и очередь сообщений. Для управления такими связками используется Docker Compose.
version: "3.9"
services:
app:
build: .
ports:
- "3000:3000"
depends_on:
- db
environment:
DATABASE_URL: postgres://user:pass@db:5432/mydb
db:
image: postgres:16
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Запуск всей связки одной командой:
docker compose up -d
Частые ошибки
- Копирование всего проекта до установки зависимостей. Если сначала выполнить
COPY . ., а потомRUN npm install, Docker будет пересобирать зависимости при каждом изменении кода, а не только при изменении package.json. Правильный порядок — сначала файлы зависимостей, потом код. - Хранение секретов в Dockerfile. Пароли и API-ключи не должны попадать в образ через ENV или ARG — используйте переменные окружения при запуске контейнера или секрет-менеджеры.
- Игнорирование .dockerignore. Без этого файла в образ попадают node_modules, .git и другие ненужные файлы, что увеличивает размер образа и время сборки.
- Использование тяжёлых базовых образов. Полноценный
node:20весит гораздо больше, чемnode:20-alpine. Для продакшена почти всегда стоит выбирать облегчённые версии. - Запуск процессов от root внутри контейнера. Это снижает безопасность — лучше явно создать непривилегированного пользователя в Dockerfile.
- Хранение данных внутри контейнера. Контейнеры эфемерны: при удалении контейнера все данные внутри него теряются. Для баз данных обязательно используйте volumes.
Заключение
Docker избавляет от бесконечной настройки окружений и делает процесс разработки предсказуемым: то, что работает у вас локально, будет работать точно так же на сервере. Начните с простого Dockerfile для своего проекта, затем добавьте Docker Compose, когда появятся дополнительные сервисы вроде базы данных. Освоив базовые команды — build, run, compose up — вы уже закроете большинство повседневных задач junior-разработчика.






Комментарии
0