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 и зачем он нужен+80 XP →Образы Docker: теги, слои, реестры+90 XP →Контейнеры: запуск, управление, отладка+100 XP →
Готов учиться интерактивно?

Двигай слайдеры и наблюдай как работает математика

Начать учиться →