Что такое Docker и зачем он новичку
Docker - платформа, которая упаковывает приложение вместе со всем, что ему нужно для работы: версией языка, библиотеками, системными пакетами, настройками. Такая упаковка называется контейнером и запускается одинаково на ноутбуке разработчика, на тестовом сервере и в продакшене. Фраза "у меня всё работает" перестаёт быть отговоркой.
Что Docker даёт на практике уже на первом курсе или в первом пет-проекте:
- PostgreSQL, Redis или RabbitMQ поднимаются одной командой, без установки в систему;
- можно держать рядом проекты на Python 3.9 и 3.13, и они не мешают друг другу;
- новый участник команды запускает проект за минуты, а не за день;
- деплой сводится к "собери образ и запусти его на сервере".
Контейнер часто путают с виртуальной машиной. Разница принципиальная: виртуальная машина эмулирует целый компьютер со своим ядром ОС, а контейнеры используют ядро хоста и изолируют только процессы, файлы и сеть. Поэтому контейнер стартует за секунды и весит десятки мегабайт, а не гигабайты.
Как установить Docker и проверить, что он работает
- Windows и macOS. Скачайте Docker Desktop с docs.docker.com. На Windows 10/11 он работает поверх WSL 2: установщик предложит включить его, либо выполните в PowerShell от администратора
wsl --installи перезагрузитесь. - Linux. Ставьте Docker Engine из официального репозитория Docker по инструкции для вашего дистрибутива. Пакет
docker.ioиз стандартных репозиториев Ubuntu тоже работает, но обычно отстаёт по версии. - Проверка. Выполните в терминале:
Последняя команда скачает крошечный тестовый образ и выведет приветствие. Если оно появилось, всё установлено правильно.docker --version docker compose version docker run hello-world
Docker Desktop бесплатен для личного использования, обучения и небольших компаний; для крупных организаций нужна платная подписка. Точные пороги по численности и выручке смотрите в актуальных условиях на сайте Docker. Docker Engine в Linux распространяется свободно.
Из России загрузка образов с Docker Hub временами бывает медленной или нестабильной. Если docker pull зависает, пропишите зеркало реестра в параметре registry-mirrors файла daemon.json (в Docker Desktop - в Settings, раздел Docker Engine) и перезапустите Docker.
Образ, контейнер, реестр: три главных понятия
Всё в Docker держится на трёх словах:
- Образ (image) - шаблон только для чтения: файловая система с ОС-основой, зависимостями и кодом. Состоит из слоёв, каждый слой - результат одной инструкции сборки. Образы различаются тегами:
python:3.13-slim,postgres:17,nginx:latest. - Контейнер (container) - запущенный экземпляр образа. Из одного образа можно запустить сколько угодно независимых контейнеров. Изменения внутри контейнера живут, пока он существует, и пропадают после удаления.
- Реестр (registry) - хранилище образов. Главный публичный - Docker Hub, есть GitHub Container Registry, облачные реестры и собственные.
Аналогия из программирования: образ - это класс, контейнер - объект этого класса. Аналогия из жизни: образ - установочный диск, контейнер - установленная с него программа, а реестр - магазин дисков.
Тег latest не значит "самый свежий". Это просто тег по умолчанию, и он может указывать на что угодно. В проектах всегда фиксируйте конкретную версию, иначе через полгода сборка внезапно поменяет поведение.
Основные команды Docker
Для старта хватит полутора десятков команд. Остальное ищется через docker КОМАНДА --help.
| Команда | Что делает |
|---|---|
docker pull nginx:1.27 | Скачать образ из реестра |
docker images | Список локальных образов |
docker run -d -p 8080:80 nginx | Создать и запустить контейнер в фоне |
docker ps / docker ps -a | Работающие / все контейнеры, включая остановленные |
docker logs -f web | Логи контейнера в реальном времени |
docker exec -it web sh | Открыть оболочку внутри работающего контейнера |
docker stop web / docker start web | Остановить / снова запустить |
docker rm web | Удалить остановленный контейнер |
docker rmi nginx:1.27 | Удалить образ |
docker build -t myapp:1.0 . | Собрать образ из Dockerfile в текущей папке |
docker system prune | Удалить остановленные контейнеры, неиспользуемые сети и висячие образы |
Самые нужные флаги docker run:
-d- запустить в фоне;-p 8080:80- пробросить порт: слева порт на вашем компьютере, справа порт внутри контейнера;--name web- дать контейнеру имя, чтобы не копировать ID;-e KEY=value- передать переменную окружения;-v- подключить том или папку;--rm- удалить контейнер сразу после остановки.
Пример: docker run -d --name web -p 8080:80 nginx, затем откройте http://localhost:8080 и увидите стартовую страницу nginx.
Dockerfile: собираем свой образ
Dockerfile - текстовый файл с инструкциями, как собрать образ. Пусть есть маленькое приложение на Flask: файл app.py и requirements.txt со строкой flask. Dockerfile для него:
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["flask", "--app", "app", "run", "--host=0.0.0.0"]
Что делает каждая строка:
FROM- базовый образ. Вариантslimзаметно легче полного.WORKDIR- рабочая папка внутри образа, дальнейшие команды выполняются в ней.COPY requirements.txt .иRUN pip install- сначала только зависимости. Docker кеширует слои: пока requirements.txt не менялся, пакеты не будут переустанавливаться при каждой правке кода.COPY . .- копирование остального кода.EXPOSE- документирует порт; сам порт наружу не открывает, это делает-p.CMD- команда запуска контейнера.--host=0.0.0.0обязателен: приложение, слушающее 127.0.0.1, недоступно снаружи контейнера.
Сборка и запуск:
docker build -t flask-demo:1.0 .
docker run --rm -p 5000:5000 flask-demo:1.0
Рядом положите файл .dockerignore со строками .git, .venv, __pycache__, .env. Так в образ не попадут лишние мегабайты и секреты. Зачем вообще нужен requirements.txt, рассказано в статье про venv и pip.
Docker Compose: несколько контейнеров одной командой
Реальному приложению почти всегда нужна база данных, иногда кеш и очередь. Запускать каждый контейнер руками с десятком флагов неудобно. Docker Compose описывает все сервисы в одном YAML-файле compose.yaml (старое имя docker-compose.yml тоже поддерживается):
services:
web:
build: .
ports:
- "5000:5000"
environment:
DATABASE_URL: postgresql://app:secret@db:5432/app
depends_on:
- db
db:
image: postgres:17
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: app
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Обратите внимание на адрес базы: хост называется db, по имени сервиса. Compose создаёт общую сеть, и контейнеры находят друг друга по именам. Строка version: "3.8" в начале файла, которую до сих пор копируют из старых туториалов, не нужна: по документации Docker этот ключ устарел, игнорируется и вызывает предупреждение.
Команды Compose:
docker compose up -d # собрать и запустить всё в фоне
docker compose ps # статус сервисов
docker compose logs -f web
docker compose down # остановить и удалить контейнеры
docker compose down -v # то же плюс удалить тома с данными
Пишите docker compose через пробел. Отдельная утилита docker-compose через дефис - первая версия Compose, которая больше не поддерживается.
Где хранить данные: тома и bind mount
Файловая система контейнера временная. Удалили контейнер с PostgreSQL без тома - потеряли базу. Для постоянных данных есть два механизма:
- Том (volume) - хранилище, которым управляет Docker:
-v pgdata:/var/lib/postgresql/data. Подходит для баз данных и всего, что должно пережить пересоздание контейнера. Список томов -docker volume ls. - Bind mount - папка с вашего компьютера, подключённая внутрь:
-v ./src:/app/src. Удобно при разработке: правите код в редакторе, контейнер сразу видит изменения.
Команда docker compose down -v удаляет тома вместе с данными базы. Привычка добавлять -v "для чистоты" однажды сотрёт вашу локальную базу с тестовыми данными. Без флага тома сохраняются, и после up всё будет на месте.
Типичные ошибки новичков в Docker
- port is already allocated. Порт на хосте занят другим контейнером или программой. Смените левую часть:
-p 8081:80, или найдите занявший процесс. - permission denied ... /var/run/docker.sock в Linux. Пользователь не в группе docker. Выполните
sudo usermod -aG docker $USERи перелогиньтесь. Учтите, что членство в этой группе фактически даёт права root. - Контейнер сразу завершается. Контейнер живёт, пока работает главный процесс. Смотрите
docker logs имя: чаще всего приложение упало при старте или команда завершилась сама. - Из контейнера не подключиться к localhost. Внутри контейнера localhost - это сам контейнер. Обращайтесь к соседнему сервису по имени из Compose, а к хосту из Docker Desktop - через
host.docker.internal. - Образ весит гигабайт. Используйте slim- или alpine-образы,
.dockerignoreи флаг--no-cache-dirу pip. - Закончилось место на диске. Старые образы и слои копятся. Посмотреть -
docker system df, почистить -docker system prune.
Docker тесно связан с Linux: внутри контейнеров почти всегда Linux, и без базовых команд терминала не обойтись. Освежите их по шпаргалке команд Linux, а если приложение за прокси отдаёт ошибку 502, загляните в разбор кодов ответов HTTP. Больше материалов - в разделе Docker.
