Перейти к основному содержимому

Основы работы с контейнерами

Разработчику Инженеру

Контейнеры в работе разработчика

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

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

image-1.png

Схема ВМ и контейнера — image.png в той же главе.

Углубление (Kubernetes, Helm, прод) — 8.06 Контейнеризация и оркестрация. Ниже — первые шаги в 4.04.


Мини-словарь

ТерминСмысл
Образ (image)Неизменяемый шаблон (слои файловой системы + метаданные)
КонтейнерЗапущенный экземпляр образа
DockerfileРецепт сборки образа
RegistryХранилище образов (Docker Hub)
Docker ComposeНесколько контейнеров одним файлом compose.yaml
Docker EngineДемон, который запускает контейнеры на машине

Цепочка развёртывания bare metal → ВМ → контейнер — четыре модели.


Установка

  • Windows / macOSDocker 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 postgresShell внутри
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 volumepgdata — 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 --from=build /app/dist ./dist
COPY --from=build /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 берётся из кэша.

Порядок важен:

  1. Сначала файлы зависимостей → RUN install
  2. Потом исходники → 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, Swarm8.06 / 111
Kubernetes8.06 / 117
Локальный стек для вебаВеб-разработка
CI/CD8.04 DevOps