Docker — Контейнеризация с нуля
Что такое контейнеры, зачем нужен Docker, как запустить первый Hello World. Создание сред для разработки и тестирования. Сравнение с альтернативами.
🐳 Что такое Docker
Docker — это платформа для разработки, доставки и запуска приложений в контейнерах. Контейнер — это изолированная среда, которая содержит всё необходимое для работы приложения: код, библиотеки, системные инструменты.
Представьте, что вы переезжаете. Вместо того чтобы таскать вещи по одной,
вы упаковываете всё в коробки. Каждая коробка — самодостаточная:
открыл — и всё на месте.
Docker-контейнер — такая же "коробка" для приложения. Внутри — код,
зависимости, настройки. Работает одинаково везде: на вашем ноутбуке,
на сервере, в облаке.
Зачем нужен Docker?
Проблема "У меня работает": Код работает на вашем компьютере, но падает на сервере. Разные версии Python, библиотек, ОС — всё влияет.
Решение Docker: Упаковываете приложение со всеми зависимостями. Если работает в контейнере локально — будет работать везде.
Кто использует Docker?
- Разработчики — одинаковая среда для всей команды
- DevOps — простой деплой, CI/CD пайплайны
- Тестировщики — изолированные среды для тестов
- Компании — Google, Netflix, Spotify, Uber и миллионы других
🧱 Ключевые концепции
Dockerfile → (сборка) → Image → (запуск) → Container
Один образ = много контейнеров. Как один рецепт торта = много тортов.
⚔️ Контейнеры vs Виртуальные машины
Контейнеры часто сравнивают с виртуальными машинами (VM). Оба обеспечивают изоляцию, но работают по-разному:
Сравнение
| Параметр | 🐳 Контейнеры | 🖥️ VM |
|---|---|---|
| Размер | МБ (10-500 MB) | ГБ (1-20 GB) |
| Запуск | Секунды | Минуты |
| Изоляция | Процессы (namespace) | Полная (отдельная ОС) |
| Ресурсы | Минимальный overhead | Значительный overhead |
| Плотность | 100+ на хосте | 5-20 на хосте |
| ОС | Общее ядро с хостом | Своя ОС |
Контейнеры: Микросервисы, CI/CD, разработка,
когда нужна скорость и эффективность.
VM: Когда нужна полная изоляция, разные ОС на одном железе,
legacy-приложения, требования безопасности.
⚙️ Установка Docker
👋 Hello World — Первый контейнер
Запустим ваш первый контейнер! Docker предоставляет специальный
тестовый образ hello-world:
Вы только что запустили свой первый Docker-контейнер! Что произошло:
1. Docker не нашёл образ локально
2. Скачал его с Docker Hub
3. Создал контейнер из образа
4. Запустил контейнер, который вывел сообщение
5. Контейнер завершился
Запустим что-то полезное — Nginx
Откройте http://localhost:8080 в браузере — вы увидите страницу приветствия Nginx!
Управление контейнером
📝 Dockerfile — Создаём свой образ
Dockerfile — это рецепт для создания образа. Давайте создадим образ для простого Python-приложения:
Шаг 1: Создаём приложение
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return '🐳 Hello from Docker! 🎉' @app.route('/health') def health(): return 'OK' if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
flask==3.0.0 gunicorn==21.2.0
Шаг 2: Создаём Dockerfile
# Базовый образ — Python 3.11 на Alpine Linux (минимальный размер) FROM python:3.11-alpine # Метаданные LABEL maintainer="you@example.com" LABEL version="1.0" # Рабочая директория внутри контейнера WORKDIR /app # Копируем файл зависимостей отдельно (для кеширования слоёв) COPY requirements.txt . # Устанавливаем зависимости RUN pip install --no-cache-dir -r requirements.txt # Копируем код приложения COPY app.py . # Переменные окружения ENV FLASK_APP=app.py ENV FLASK_ENV=production # Открываем порт EXPOSE 5000 # Команда запуска (production-ready с gunicorn) CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
Шаг 3: Собираем и запускаем
• Минимальный базовый образ — используйте alpine или slim версии
• Кеширование слоёв — COPY requirements.txt до COPY кода
• Один процесс — один контейнер = один процесс
• Не запускайте от root — создайте отдельного пользователя
• .dockerignore — исключайте ненужные файлы (node_modules, .git)
Файл .dockerignore
# Игнорируем при сборке (как .gitignore)
.git
.gitignore
__pycache__
*.pyc
*.pyo
.env
.venv
venv
node_modules
*.log
.DS_Store
Dockerfile
docker-compose*.yml
README.md
🛠️ Среды разработки и тестирования
Одна из главных суперсил Docker — создание одинаковых сред для всей команды и всех этапов: разработка → тестирование → продакшен.
Проблема: "У Васи Python 3.8, у Пети 3.11, на сервере 3.9.
У всех разные версии библиотек. Код работает по-разному."
Решение: Docker-контейнер с фиксированными версиями всего.
Работает одинаково у всех и везде.
Примеры готовых сред
--name postgres-dev \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
postgres:16-alpine
--name redis-dev \
-p 6379:6379 \
redis:alpine
--name mongo-dev \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=secret \
-p 27017:27017 \
mongo:7
--name rabbitmq-dev \
-p 5672:5672 \
-p 15672:15672 \
rabbitmq:3-management
--name elastic-dev \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
-p 9200:9200 \
elasticsearch:8.11.0
--name mailhog \
-p 1025:1025 \
-p 8025:8025 \
mailhog/mailhog
Docker Compose — Несколько сервисов вместе
Когда нужно запустить несколько контейнеров (приложение + БД + Redis), используйте Docker Compose:
version: '3.8' services: # Наше приложение app: build: . ports: - "5000:5000" environment: - DATABASE_URL=postgresql://user:pass@db:5432/myapp - REDIS_URL=redis://redis:6379 depends_on: - db - redis volumes: - .:/app # Для hot-reload при разработке # PostgreSQL db: image: postgres:16-alpine environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=myapp volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" # Redis redis: image: redis:alpine ports: - "6379:6379" # Adminer — веб-интерфейс для БД adminer: image: adminer ports: - "8080:8080" volumes: pgdata:
• Onboarding за минуты — новый разработчик: git clone + docker compose up
• Изолированные проекты — разные версии Python/Node для разных проектов
• Чистая система — ничего не устанавливается на хост
• Идентичность prod/dev — те же образы, что и в продакшене
• Тестирование — запуск тестов в чистом окружении
⌨️ Основные команды Docker
Работа с образами
| Команда | Описание |
|---|---|
docker pull nginx |
Скачать образ из Docker Hub |
docker images |
Список локальных образов |
docker build -t myapp:1.0 . |
Собрать образ из Dockerfile |
docker rmi nginx |
Удалить образ |
docker push myapp:1.0 |
Загрузить образ в реестр |
Работа с контейнерами
| Команда | Описание |
|---|---|
docker run -d -p 80:80 nginx |
Создать и запустить контейнер |
docker ps |
Список запущенных контейнеров |
docker ps -a |
Все контейнеры (включая остановленные) |
docker stop <id/name> |
Остановить контейнер |
docker start <id/name> |
Запустить остановленный контейнер |
docker rm <id/name> |
Удалить контейнер |
docker exec -it <name> bash |
Зайти внутрь контейнера |
docker logs -f <name> |
Логи контейнера в реальном времени |
Docker Compose
| Команда | Описание |
|---|---|
docker compose up -d |
Запустить все сервисы |
docker compose down |
Остановить и удалить |
docker compose ps |
Статус сервисов |
docker compose logs -f |
Логи всех сервисов |
docker compose build |
Пересобрать образы |
docker compose exec app bash |
Зайти в контейнер сервиса |
Очистка системы
| Команда | Описание |
|---|---|
docker system prune |
Удалить неиспользуемые данные |
docker system prune -a |
+ все неиспользуемые образы |
docker volume prune |
Удалить неиспользуемые тома |
docker system df |
Сколько места занимает Docker |
🔄 Альтернативы Docker
Docker — не единственное решение для контейнеризации. Вот популярные альтернативы и когда их использовать:
- ✓ Самый популярный
- ✓ Docker Hub — миллионы образов
- ✓ Отличный DX (Developer Experience)
- ✓ Docker Desktop для Win/Mac
- ✓ Без демона (daemonless)
- ✓ Работает без root
- ✓ Совместим с Dockerfile
- ✗ Меньше экосистема
- ✓ Используется в Kubernetes
- ✓ Легковесный
- ✗ Нет CLI для людей
- ✗ Не для разработчиков
- ✓ Создан для Kubernetes
- ✓ Минимальный overhead
- ✗ Только для K8s
- ✗ Нельзя использовать standalone
- ✓ Полноценная ОС в контейнере
- ✓ Systemd работает
- ✗ Не для микросервисов
- ✗ Тяжелее Docker
- ✓ Автомасштабирование
- ✓ Self-healing
- ✓ Для продакшена
- ✗ Сложность настройки
Для разработки: Docker — стандарт, лучший DX
Для безопасности: Podman — rootless из коробки
Для Kubernetes: containerd или CRI-O
Для VM-подобных контейнеров: LXC/LXD
В 99% случаев — начните с Docker. Переходите на альтернативы,
когда появятся конкретные причины.
❓ Частые вопросы
Docker Desktop — бесплатный для личного использования и небольших компаний (до 250 сотрудников и $10M выручки). Для крупных компаний — платная подписка ($5-21/мес).
Альтернатива: На Linux можно использовать Docker Engine напрямую. Или Podman — полностью бесплатный.
• CPU: ~0% overhead
• Memory: ~0% overhead
• Disk I/O: ~1-3% overhead (overlay filesystem)
• Network: ~1% overhead
Для большинства приложений разница незаметна.
1. Соберите новый образ с обновлённым кодом
2. Остановите старый контейнер
3. Запустите новый контейнер из нового образа
docker build -t myapp:2.0 .docker stop myapp && docker rm myappdocker run -d --name myapp myapp:2.0Или используйте Docker Compose / Kubernetes для автоматизации.
Решение — Volumes:
docker run -v mydata:/app/data ...Volume хранится на хосте, переживает удаление контейнера.
Для баз данных всегда используйте volumes:
docker run -v pgdata:/var/lib/postgresql/data postgres
1. Docker-in-Docker (dind):
Запуск полноценного Docker daemon внутри контейнера. Используется в CI/CD.
2. Docker-out-of-Docker:
Монтирование socket хоста внутрь контейнера:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...⚠️ Второй вариант даёт контейнеру полный контроль над Docker хоста — небезопасно!
• WSL 2 (рекомендуется) — настоящее ядро Linux в Windows
• Hyper-V — легковесная VM с Linux
Linux-контейнеры работают внутри Linux (WSL2/VM). Есть также Windows-контейнеры (для .NET Framework), но они редко используются.
Для разработчика разницы практически нет — всё работает одинаково.
Контейнер — это просто процесс. Если каждый использует 50MB RAM, на сервере с 32GB можно запустить 500+ контейнеров.
На практике:
• Ноутбук разработчика: 10-30 контейнеров
• Продакшен-сервер: 50-200 контейнеров
• Kubernetes-кластер: тысячи контейнеров
1. Установите Docker — Docker Desktop для Win/Mac или Docker Engine для Linux
2. Запустите hello-world — docker run hello-world
3. Контейнеризируйте свой проект — напишите Dockerfile
4. Изучите Docker Compose — для нескольких сервисов
5. Переходите к Kubernetes — когда нужна оркестрация
Docker — один из важнейших инструментов современного разработчика.
Потратьте день на изучение — сэкономите месяцы в будущем.