Что такое Docker и зачем разработчикам контейнеры
Основы3 минРедакция Innovialabs
Коротко
Docker упаковывает приложение вместе со всеми зависимостями в образ, из которого запускается изолированный контейнер. Поэтому код одинаково работает на ноутбуке разработчика, в CI и на сервере.
Короткий ответ
Docker — инструмент, который упаковывает приложение вместе с окружением: нужной версией языка, библиотеками, системными пакетами и настройками. Такую упаковку можно запустить на любой машине с Docker, и она поведет себя одинаково.
Запущенная упаковка называется контейнером. Это обычный процесс операционной системы, но изолированный: у него своя файловая система, своя сеть и свои ограничения по ресурсам.
Четыре ключевых понятия
- Образ (image) — неизменяемый шаблон: файловая система с приложением и зависимостями плюс команда запуска. Образ состоит из слоев, и одинаковые слои переиспользуются между образами.
- Контейнер (container) — запущенный экземпляр образа. Из одного образа можно запустить сколько угодно контейнеров.
- Dockerfile — текстовый рецепт сборки образа: от какого базового образа отталкиваться, что скопировать, что установить, что запускать.
- Реестр (registry) — хранилище образов. Публичный пример — Docker Hub, также есть приватные реестры в GitHub, GitLab и облаках. Сервер скачивает готовый образ из реестра, а не собирает его заново.
Аналогия: Dockerfile — рецепт, образ — замороженное готовое блюдо, контейнер — порция, которую разогрели и подали.
Пример: hello-world за пять минут
Самая короткая проверка, что Docker установлен:
docker run hello-world
Теперь свое приложение. Файл app.py:
print("Hello from Docker")
Рядом Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY app.py .
CMD ["python", "app.py"]
Собираем образ и запускаем контейнер:
docker build -t hello-app .
docker run --rm hello-app
На машине не нужно ставить Python: нужная версия уже лежит внутри образа. Флаг --rm удаляет контейнер после завершения.
Чтобы отправить образ в реестр, его тегируют адресом реестра и выполняют docker push. На сервере достаточно docker pull и docker run.
Какие проблемы решает Docker
- «У меня работает». Окружение описано в Dockerfile и одинаково у всех: у разработчиков, в CI и на продакшене. Разные версии библиотек на разных машинах перестают быть источником багов.
- Изоляция. Два проекта, которым нужны разные версии Node.js или PostgreSQL, спокойно живут на одном сервере.
- Воспроизводимый деплой. На сервер выкатывается тот же образ, что прошел тесты. Откат — запуск предыдущего тега образа.
- Быстрый старт новичка. Вместо длинной инструкции по установке —
docker compose up, и проект со всеми сервисами поднят. - Основа для оркестрации. Kubernetes и другие платформы работают именно с контейнерами.
Частые ошибки новичков
- Хранить данные внутри контейнера. При удалении контейнера они пропадут. Для баз и загрузок используйте volumes.
- Тег
latestна продакшене. Непонятно, какая именно версия запущена. Используйте явные теги, например по номеру версии или хешу коммита. - Секреты в образе. Пароли и ключи не копируют в Dockerfile — их передают через переменные окружения или менеджер секретов.
- Огромные образы. Берите slim-образы, добавьте
.dockerignore, а для компилируемых языков используйте multi-stage сборку. - Несколько сервисов в одном контейнере. Правило: один контейнер — один процесс. Базу и приложение запускают отдельно и связывают через сеть.