Основы работы с контейнерами
Контейнеры в работе разработчика
Контейнер — изолированная среда: приложение, зависимости и настройки упакованы вместе и ведут себя одинаково на вашем ноутбуке и на сервере. Один и тот же образ (image) снимает расхождения окружения, когда на одной машине "работает", а на другой — нет.
Контейнер легче полной виртуальной машины (ВМ): процессы делят ядро хоста, но видят свою файловую систему и сеть. Сравнение моделей — Контейнеризация:

Схема ВМ и контейнера — image.png в той же главе.
Углубление (Kubernetes, Helm, прод) — 8.06 Контейнеризация и оркестрация. Ниже — первые шаги в 4.04.
Мини-словарь
| Термин | Смысл |
|---|---|
| Образ (image) | Неизменяемый шаблон (слои файловой системы + метаданные) |
| Контейнер | Запущенный экземпляр образа |
| Dockerfile | Рецепт сборки образа |
| Registry | Хранилище образов (Docker Hub) |
| Docker Compose | Несколько контейнеров одним файлом compose.yaml |
| Docker Engine | Демон, который запускает контейнеры на машине |
Цепочка развёртывания bare metal → ВМ → контейнер — четыре модели.
Установка
- Windows / macOS — Docker Desktop.
- Linux — Docker Engine + Compose plugin.
Перед первым запуском — Запуск и перезапуск приложений (терминал, порты, остановка).
Проверка:
docker version
docker run hello-world
hello-world скачает образ и выведет короткое сообщение — значит Engine работает.
Первый полезный контейнер — PostgreSQL
Локальная БД для pet-проекта без установки PostgreSQL в систему:
docker run -d --name mypg \
-e POSTGRES_PASSWORD=devpass \
-e POSTGRES_DB=todo \
-p 5432:5432 \
postgres:16
| Флаг | Смысл |
|---|---|
-d | Фон (detached) |
--name mypg | Имя контейнера |
-e | Переменная окружения внутри контейнера |
-p 5432:5432 | Порт хоста → порт контейнера |
Подключение из приложения:
- хост
localhost:5432; - пользователь
postgres; - пароль
devpass; - база
todo.
Остановка:
docker stop mypg
docker rm mypg
Секреты в prod хранят отдельно — не devpass в истории shell; см. .env. SQL и подключение — 3.07 SQL.
Docker Compose — API + БД
Когда сервисов несколько, удобнее Compose. Готовые стеки — Lab / 11111. Минимальный пример:
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: devpass
POSTGRES_DB: todo
ports:
- "5432:5432"
docker compose up -d
docker compose down
Связь с манифестами зависимостей — Dockerfile рядом с package.json / requirements.txt.
Dockerfile в двух словах
Образ собирают из Dockerfile — пошаговые инструкции:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Сборка и запуск:
docker build -t my-api .
docker run -p 3000:3000 my-api
Готовые шаблоны — Dockerfile — 10 типовых образов. CI-сборка — GitHub Actions.
Частые команды
| Команда | Действие |
|---|---|
docker ps | Запущенные контейнеры |
docker ps -a | Все контейнеры |
docker logs mypg | Лог контейнера |
docker exec -it mypg psql -U postgres | Shell внутри |
docker image ls | Локальные образы |
18 команд с разбором — DevOps-шпаргалка / Docker.
Volumes — данные после перезапуска
Контейнер без volume теряет изменения в файловой системе при удалении. Volume — постоянное хранилище на хосте.
docker run -d --name mypg \
-v pgdata:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=devpass \
postgres:16
| Тип | Смысл |
|---|---|
| Named volume | pgdata — Docker управляет путём |
| Bind mount | -v ./data:/var/lib/postgresql/data — папка на хосте |
Bind mount удобен для dev; named volume — для prod. Данные переживают docker rm (volume удаляют отдельно).
Сети Docker
По умолчанию контейнеры в одной user-defined network видят друг друга по имени сервиса:
services:
api:
build: .
ports:
- "3000:3000"
db:
image: postgres:16
Из api строка подключения: postgresql://postgres:pass@db:5432/todo — хост db, не localhost.
Multi-stage Dockerfile
Сборка в одном образе, запуск из минимального финального слоя — меньше размер и поверхность атаки:
FROM node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY /app/dist ./dist
COPY /app/node_modules ./node_modules
CMD ["node", "dist/main.js"]
Шаблоны — Lab / 11113.
.dockerignore
Как .gitignore — не копировать в контекст сборки:
node_modules
.git
.env
*.md
dist
Меньше контекст → быстрее docker build. Секреты не попадают в образ случайно.
Кэш слоёв
Каждая строка Dockerfile — слой. Если COPY package.json не менялся, слой RUN npm ci берётся из кэша.
Порядок важен:
- Сначала файлы зависимостей →
RUN install - Потом исходники →
COPY . .
Иначе каждая правка кода пересобирает все зависимости.
Redis в контейнере
Кэш и очереди локально:
docker run -d --name redis -p 6379:6379 redis:7-alpine
Подключение из приложения: redis://localhost:6379. NoSQL.
Полный compose — API + PostgreSQL
services:
api:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://postgres:devpass@db:5432/todo
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: devpass
POSTGRES_DB: todo
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
docker compose up -d --build
docker compose logs -f api
Стек для веб-проекта.
Healthcheck
Docker перезапускает или помечает unhealthy контейнер:
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 5
depends_on с condition: service_healthy — API стартует после готовности БД.
Типичные ошибки
| Сообщение | Причина | Решение |
|---|---|---|
port is already allocated | порт занят на хосте | другой -p 5433:5432 или stop другого процесса |
permission denied (Linux) | права на socket | добавить user в группу docker |
no space left on device | диск / образы | docker system prune |
connection refused к localhost из другого контейнера | localhost = сам контейнер | имя сервиса в compose network |
| старые данные в БД | volume сохранился | docker volume rm или новый volume |
Windows и WSL
Docker Desktop на Windows часто использует WSL2. Пути вида -v C:\data:/data работают через преобразование; для dev проще держать проект внутри Linux filesystem WSL (\\wsl$\...). Подробнее — 1121 Docker Desktop.
Отладка контейнера
docker logs -f mypg # поток логов
docker exec -it mypg bash # shell внутри
docker inspect mypg # JSON с IP, mounts, env
docker stats # CPU/RAM в реальном времени
Если приложение падает сразу — docker logs покажет stack trace до exec.
Безопасность (минимум)
- Не монтируйте
-v /:/hostи не давайте--privilegedбез понимания — Опасные скрипты. - Не публикуйте образы с секретами внутри слоёв.
- Обновляйте базовые образы (
node:20-alpine→ актуальный patch).
Подробнее — Безопасность в Docker.
Что дальше
| Цель | Куда |
|---|---|
| Архитектура Docker, Swarm | 8.06 / 111 |
| Kubernetes | 8.06 / 117 |
| Локальный стек для веба | Веб-разработка |
| CI/CD | 8.04 DevOps |