Docker с нуля: контейнеры, образы, Compose
Что такое Docker
Docker — платформа для запуска приложений в контейнерах. Контейнер упаковывает код, зависимости и конфигурацию в один независимый юнит.
Главная проблема без Docker: «работает на моей машине, не работает на сервере» — разные версии Node.js, Python, системных библиотек. Docker решает это — приложение везёт своё окружение с собой.
Контейнеры vs VM
VM: Host OS → Hypervisor → Guest OS → Runtime → App
Контейнер: Host OS → Docker Engine → Container (Runtime + App)
VM запускает полноценную ОС (гигабайты, минуты старта). Контейнер — изолированный процесс, использующий ядро хоста (мегабайты, секунды старта).
Базовые команды
# Образы
docker pull nginx:alpine # скачать образ
docker images # список образов
docker rmi nginx:alpine # удалить образ
# Контейнеры
docker run -d -p 8080:80 nginx # запустить в фоне
docker ps # работающие контейнеры
docker ps -a # все контейнеры
docker logs -f <id> # логи в реальном времени
docker exec -it <id> sh # войти в контейнер
docker stop <id> # остановить
docker rm <id> # удалить
Dockerfile
Dockerfile — рецепт для сборки своего образа:
FROM node:20-alpine
WORKDIR /app
# Сначала зависимости (лучший кэш слоёв)
COPY package*.json ./
RUN npm ci --only=production
# Потом код
COPY src/ ./src/
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "src/index.js"]
docker build -t my-app .
docker run -p 3000:3000 my-app
Слои и кэш
Каждая инструкция — отдельный слой. Docker кэширует неизменённые слои. Изменение слоя инвалидирует все последующие.
Правило: стабильное (зависимости) — выше, изменяемое (код) — ниже.
Multi-stage builds
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o server .
FROM scratch
COPY --from=builder /app/server /server
CMD ["/server"]
Итог: образ с Go бинарником ~15MB вместо ~850MB.
Docker Compose
Compose описывает многоконтейнерное приложение:
services:
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: secret
api:
build: .
ports:
- "8000:8000"
depends_on:
- db
environment:
DATABASE_URL: postgres://postgres:secret@db:5432/myapp
volumes:
pgdata:
docker compose up -d # запустить всё
docker compose down # остановить
docker compose logs -f # логи всех сервисов
Service Discovery
В Compose-сети сервисы находят друг друга по имени: db, redis, api. Docker разрешает DNS автоматически.
Volumes
# Named volume — данные переживают docker compose down
- pgdata:/var/lib/postgresql/data
# Bind mount — для разработки
- ./src:/app/src
# Tmpfs — в памяти
tmpfs: /tmp
Сети
networks:
frontend:
backend:
services:
nginx:
networks: [frontend, internal]
api:
networks: [internal, backend]
db:
networks: [backend] # недоступна с frontend
CI/CD Pipeline
docker build -t app:${GIT_SHA} .
docker push ghcr.io/org/app:${GIT_SHA}
# деплой с конкретным тегом — воспроизводимость
Уроки модуля
- Что такое Docker: контейнеры vs VM
- Образы: слои, теги, реестры
- Контейнеры: запуск и управление
- Dockerfile: создаём образ
- Слои и кэш
- Multi-stage builds
- Docker Compose: основы
- Volumes
- Сети