Docker – быстрый старт
Денис Сучков
Docker — это инструмент, который упаковывает приложение вместе со всеми его зависимостями в изолированный «контейнер» и запускает его одинаково на любой машине. Если ты разрабатываешь бэкенд — Docker нужен будет почти везде: для локальной разработки, для тестов, для CI/CD, для прода.
В этой статье разберём базу за 20 минут — что такое контейнер и образ, основные команды CLI, и как написать свой первый Dockerfile.
Основные понятия
Docker Engine — ядро Docker'а, фоновый сервис (демон dockerd),
который умеет создавать образы и контейнеры и управлять ими. Состоит из
трёх частей:
- сервер — длительно работающий процесс
dockerd, который реально создаёт образы и контейнеры; - API — интерфейс для общения с этим процессом;
- CLI — командная строка
docker, которой ты пользуешься в терминале.
- Dockerfile — текстовый файл с инструкциями «как собрать образ». Это рецепт.
- Docker image — собранный по рецепту шаблон. Набор файлов и метаданных, из которого можно запускать контейнеры. Это «торт по рецепту».
- Docker container — запущенный экземпляр образа. Изолированный процесс с собственной файловой системой и сетевым стеком. Это «съеденный кусок торта». Контейнер можно остановить, удалить, перезапустить — образ при этом остаётся.
Базовые команды — попробуй прямо здесь
Ниже — симулированный Docker-терминал. Печатай команды, нажимай Enter.
В фоне уже работает контейнер nginx — попробуй docker ps,
чтобы его увидеть. Дальше — docker run hello-world,
docker pull redis, docker images.
Docker terminal (симуляция). Введи "help" для списка команд. Уже работает: контейнер nginx на порту 8080. Попробуй: docker ps | docker run hello-world | docker pull redis
ⓘ Это симулятор: команды не запускают настоящий Docker, но возвращают правдоподобные выводы для типичных команд.
Что важно понимать про эти команды:
docker run nginxделает две вещи: если образаnginxнет локально — скачивает его из Docker Hub, потом создаёт из него новый контейнер и запускает.docker psпоказывает только работающие контейнеры. Чтобы увидеть остановленные — нужен флаг-a(all).docker stop <id>отправляет процессу внутри контейнера сигналSIGTERMи ждёт 10 секунд. Если процесс не завершился — добиваетSIGKILL. Это важно для graceful shutdown в твоих сервисах.- ID контейнера можно сокращать: вместо
a3f9d8e1c7b2хватит первых 3-4 символов, если они уникальны.
Полезные флаги
-d(detached) — запустить в фоне, не «прицепляться» к выводу контейнера. Без негоdocker runблокирует терминал.-p HOST:CONTAINER— пробросить порт из хоста в контейнер.-p 8080:80= «когда я обращаюсь на localhost:8080, веди меня на порт 80 внутри контейнера». Без этого порт контейнера наружу не виден.-it— интерактивно + псевдо-TTY. Нужно чтобы войти в shell контейнера:docker run -it ubuntu bash.--name myapp— дать контейнеру читаемое имя вместо случайного angry_einstein.-v /host/path:/container/path— монтировать папку с хоста внутрь контейнера. Так данные не исчезают при пересоздании контейнера.-e VAR=value— передать переменную окружения.--rm— автоматически удалить контейнер после завершения. Удобно для одноразовых запусков.
Канонический пример «на каждый день»:
docker run -d --name web -p 8080:80 -v $(pwd)/html:/usr/share/nginx/html nginx
Расшифровка: запустить nginx в фоне (-d), назвать
контейнер web, пробросить порт 8080 на 80, смонтировать
локальную папку html внутрь контейнера в директорию,
откуда nginx раздаёт файлы. Через секунду открываешь
localhost:8080 и видишь свой index.html.
Свой Dockerfile
Dockerfile — это текстовый файл с инструкциями «как собрать образ». Каждая строка — отдельный шаг (слой), который Docker выполняет последовательно.
Ниже — живой Dockerfile для Go-приложения. Кликни по любой строке — справа появится объяснение, что эта инструкция делает и какие у неё подводные камни.
Интерактивный Dockerfile
Кликни по строке — справа объяснение. Можешь редактировать.
Сборка и запуск
Когда Dockerfile готов, собираем образ:
docker build -t myapp .
Здесь -t myapp — даём образу имя (тег), . в
конце — путь к контексту сборки (текущая директория). Контекст — это
набор файлов, которые Docker может видеть на этапе сборки. Из этого
контекста инструкции COPY копируют файлы в образ.
Запускаем:
docker run -d -p 8080:8080 --name myapp myapp Частые ошибки и проблемы
- Контейнер запустился и сразу остановился. Контейнер
живёт ровно столько, сколько работает его основной процесс. Если
основной процесс — это
echo hello, контейнер живёт секунду. Чтобы держать контейнер «навсегда», основной процесс должен быть долгоживущим: nginx, ваш сервер, sleep infinity. - Поменял код, пересобрал — изменения не появились.
Скорее всего проблема в кешировании. Если ты меняешь только Go-файл,
а перед ним стоит
RUN go mod download, Docker использует кешированный слойgo mod download— это нормально. Но если меняетсяgo.mod, кеш должен слететь. Если не слетает — попробуйdocker build --no-cache. - Образ весит 1.5 GB. Используй базовые образы поменьше:
golang:1.21-alpineвместоgolang:1.21. Или ещё лучше — multi-stage builds: сборка в одном контейнере, рантайм — в маленькомscratchилиalpine. - Контейнер не видит сервис на хосте. Из контейнера
localhost— это сам контейнер, не твой ноут. Чтобы обратиться к процессу на хосте, на Docker Desktop используйhost.docker.internal, на Linux —--network=hostили адрес172.17.0.1. - Данные исчезли после перезапуска. Файловая система
контейнера эфемерна. Всё, что записал внутрь — теряется при удалении
контейнера. Для постоянных данных используй volumes:
-v mydata:/dataили-v /host/path:/data. - «Permission denied» при монтировании папки. Процесс
в контейнере работает от UID 1 (root) или какого-то другого
пользователя — он может не иметь прав на твою папку с хоста. На Linux
это решается через
--user $(id -u):$(id -g).
Что дальше
Базы тебе хватит, чтобы начать. Дальше копаешь по запросу:
- Multi-stage builds — как делать маленькие production-образы (сборка в одном слое, рантайм в другом). У меня есть отдельная статья: Многоступенчатая сборка Docker.
- Docker Compose — чтобы поднять несколько сервисов одной командой (бэкенд + Postgres + Redis).
- Volumes и сети — управление данными и связь между контейнерами.
- Kubernetes — следующий шаг, когда контейнеров много и их надо оркестрировать. Конспект по K8s.
Забронируй место на курсе System Design
Заполни форму — когда курс будет готов, ты первым узнаешь о запуске и получишь лучшую цену. Предзапись ни к чему не обязывает.