Docker — это платформа для контейнеризации, которая позволяет упаковывать приложение со всеми его зависимостями в стандартизированный блок (контейнер) для разработки, доставки и запуска.
Основные преимущества:
- Одинаковое окружение на всех машинах
- Изоляция приложений друг от друга
- Быстрый запуск и остановка
- Экономия ресурсов по сравнению с VM
- Простота масштабирования
Структура Docker
Dockerfile → Image → Container
Ключевые компоненты
- Dockerfile: инструкции для сборки образа
- Image: шаблон для создания контейнера
- Container: запущенный экземпляр образа
- Registry: хранилище образов (например, Docker Hub)
Dockerfile — текстовый файл с инструкциями сборки Docker-образа. Инструкции выполняются сборщиком в изолированных build-контейнерах и формируют слои образа; это не тот же контейнер, который позже запускается в production.
Вот пример простого Dockerfile и объяснение основных команд:
# Используем базовый образ
FROM ubuntu:20.04
# Устанавливаем необходимые пакеты
RUN apt-get update && apt-get install -y \
python3 \
python3-pip
# Создаем рабочий каталог
WORKDIR /app
# Копируем файлы в контейнер
COPY . /app
# Устанавливаем зависимости Python
RUN pip3 install -r requirements.txt
# Определяем переменные среды
ENV APP_PORT=8000
# Открываем порт
EXPOSE $APP_PORT
# Команда, которая будет выполнена при запуске контейнера
CMD ["python3", "app.py"]
- FROM: Указывает базовый образ, на основе которого строится новый образ.
- RUN: Выполняет команды внутри образа в процессе построения. В данном случае, обновляется список пакетов и устанавливаются Python и pip.
- WORKDIR: Устанавливает рабочий каталог для следующих инструкций.
- COPY: Копирует файлы из build context в файловую систему образа.
- RUN: Устанавливает зависимости Python из файла
requirements.txt. - ENV: Определяет переменные среды.
- EXPOSE: Документирует, какой порт слушает приложение. Инструкция не публикует порт на хосте; для этого используют
docker run -pили настройкуportsв Compose. - CMD: Задает команду, которая будет выполнена при запуске контейнера.
Multistage docker:
Multi-stage build — способ использовать несколько стадий
FROMв одном Dockerfile. Из build-стадии в финальную копируют только необходимые артефакты, не включая компиляторы и другие временные зависимости.
Основная идея заключается в том, чтобы использовать один этап для сборки приложения и другой для его развертывания. Это позволяет в итоге создавать образы, которые содержат только необходимые для работы приложения компоненты, исключая избыточные зависимости и файлы сборки.
# syntax=docker/dockerfile:1
FROM alpine:latest AS builder
RUN apk --no-cache add build-base
FROM builder AS build1
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp
FROM builder AS build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp
# docker build --target build1 .
Практические примеры использования
Запуск простого веб-приложения
# Dockerfile
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
# Сборка и запуск
docker build -t myapp .
docker run -p 8000:8000 myapp
Разработка с базой данных
Используем Docker Compose v2, который запускается как
docker compose. Старый отдельный бинарникdocker-composeотносится к Compose v1.
# compose.yaml
services:
web:
build: .
ports:
- "8000:8000"
volumes:
- .:/app
depends_on:
db:
condition: service_healthy
db:
image: postgres:17
environment:
POSTGRES_PASSWORD: example
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 10
volumes:
postgres_data:
Типы хранения данных
- Volumes: постоянное хранилище, создаваемое и управляемое Docker
docker volume create mydata
docker run -v mydata:/data myapp
- Bind Mounts: прямая привязка к хост-системе
docker run -v /host/path:/container/path myapp
- tmpfs: временное хранилище в памяти (только Linux)
docker run --tmpfs /tmp myapp
Сети в Docker
- bridge: (по умолчанию) для контейнеров на одном хосте
- host: использует сеть хоста
- none: без сети
- overlay: соединяет контейнеры на разных Docker-хостах, участвующих в Swarm mode
# Создание сети
docker network create mynetwork
# Подключение контейнера к сети
docker run --network mynetwork myapp
Оптимизация образов
Используйте multi-stage builds
# Этап сборки
FROM node:16 AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
# Финальный этап
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
Минимизируйте слои
# Плохо
RUN apt-get update
RUN apt-get install -y package1
RUN apt-get install -y package2
# Хорошо
RUN apt-get update && apt-get install -y \\
package1 \\
package2
Типичные сценарии использования
Локальная разработка
# Запуск окружения разработки
docker compose up -d
# Просмотр логов
docker compose logs -f
# Перезапуск сервиса после изменений
docker compose restart web
Отладка
# Подключение к работающему контейнеру
docker exec -it container_id bash
# Просмотр логов
docker logs -f container_id
# Просмотр использования ресурсов
docker stats
Часто используемые команды
# Управление контейнерами
docker ps # Список запущенных контейнеров
docker ps -a # Все контейнеры
docker start/stop # Запуск/остановка контейнера
docker rm # Удаление контейнера
# Управление образами
docker images # Список образов
docker pull # Загрузка образа
docker build # Сборка образа
docker rmi # Удаление образа
# Работа с Docker Compose
docker compose up # Запуск сервисов
docker compose down # Остановка и удаление сервисов
docker compose logs # Просмотр логов
Docker compose
Docker Compose — инструмент для определения и запуска многоконтейнерных приложений. В YAML-файле описывают сервисы, сети, volumes, конфигурацию сборки и другие параметры, а CLI управляет жизненным циклом приложения.
Основные концепции Docker Compose Docker Compose упрощает разработку и тестирование приложений, особенно в контексте многоконтейнерных сценариев, где несколько сервисов должны взаимодействовать друг с другом.
- Файл конфигурации (
compose.yaml): Docker Compose использует YAML-файл для определения настроек и параметров каждого сервиса в многоконтейнерном приложении. В этом файле можно указать образы контейнеров, порты, сети, volumes, переменные окружения и другие настройки. Пример файлаcompose.yaml:
services:
web:
image: nginx:1.28
ports:
- "8080:80"
db:
image: mysql:8.4
environment:
MYSQL_ROOT_PASSWORD: example
- Сервисы: Каждый сервис в многоконтейнерном приложении определяется как отдельный блок в файле конфигурации. Сервисы могут взаимодействовать друг с другом посредством сетевых соединений.
- Команды CLI: Docker Compose предоставляет команды
docker compose up,docker compose down,docker compose psи другие. - Сети и объемы: Docker Compose позволяет определять сети и объемы для обеспечения связи и хранения данных между контейнерами.
Основные команды
docker run :
Запускает новый контейнер из образа.
docker run -it ubuntu:latest /bin/bash
docker ps:
Отображает список запущенных контейнеров.
docker ps
docker images:
Показывает список загруженных образов.
docker images
docker build:
Строит образ из Dockerfile.
docker build -t my_image:latest .
docker stop:
Останавливает работу одного или нескольких контейнеров.
docker stop container_id
docker rm:
Удаляет один или несколько контейнеров.
docker rm container_id
docker rmi:
Удаляет один или несколько образов.
docker rmi image_id
docker exec:
Запускает команду внутри запущенного контейнера.
docker exec -it container_id /bin/bash
docker compose up:
Запускает приложение согласно настройкам в файле compose.yaml.
docker compose up
docker network ls:
Отображает список сетей Docker.
docker network ls
docker pull:
Загружает образ из Docker Hub или другого репозитория.
docker pull nginx:latest
docker logs:
Просматривает вывод журналов контейнера.
docker logs container_id
docker inspect:
Возвращает подробную информацию о контейнере, образе, сети или томе.
docker inspect container_id
docker compose down:
Останавливает и удаляет контейнеры и сети проекта. Volumes удаляются только с флагом --volumes, а external-ресурсы не удаляются.
docker compose down
docker ps -a:
Отображает список всех контейнеров, включая остановленные.
docker ps -a
docker compose build:
Строит образы, определённые в файле compose.yaml.
docker compose build
docker exec -it:
Запускает интерактивную оболочку внутри контейнера.
docker exec -it container_id /bin/sh
docker compose logs:
Просматривает вывод журналов сервисов из compose.yaml.
docker compose logs
docker volume ls:
Отображает список созданных Docker-томов.
docker volume ls
docker compose ps:
Отображает статус сервисов, определённых в файле compose.yaml.
docker compose ps
Что могут спросить (теория)
Как создать образ Docker?
Образ Docker создается с использованием Dockerfile, который содержит инструкции для пошагового построения образа, включая базовый образ, зависимости и настройки.
Что такое Docker и для чего он используется?
Docker — платформа для контейнеризации приложений. Контейнеры изолируют процессы и делают окружение переносимым между совместимыми ОС и архитектурами; при этом они разделяют ядро хоста. Используется для доставки и развертывания программного решения на разных устройствах, упрощая эту задачу.
Что такое Docker Compose и как он упрощает развертывание многоконтейнерных приложений?
Docker Compose - инструмент для определения и управления многоконтейнерных приложений через файл конфигурации YAML, что позволяет легко запускать и масштабировать связанные службы.
Как управлять сетями в Docker?
Docker предоставляет команды для создания и управления сетями, такие как docker network create и docker network connect, позволяя контейнерам взаимодействовать через изолированные сетевые пространства.
Что такое Docker Hub?
Docker Hub - это облачный реестр образов Docker, где разработчики могут публиковать, обмениваться и загружать готовые образы для использования в своих проектах.
Что такое оркестрация контейнеров и какие инструменты вы знаете для неё?
Оркестрация контейнеров - это управление и развертывание контейнеров в крупномасштабных средах. Kubernetes, Docker Swarm и Amazon ECS - это примеры инструментов для оркестрации контейнеров.
Advanced вопросы
Как обеспечивается безопасность контейнеров в Docker?
Docker предоставляет namespaces, cgroups и capabilities для изоляции, но это не автоматическая гарантия безопасности. Нужны минимальные privileges/capabilities, непривилегированный пользователь, доверенные обновляемые образы, защита Docker socket и отказ от --privileged, если он не необходим.
Какие инструменты можно использовать для мониторинга Docker-контейнеров?
Для мониторинга Docker-контейнеров можно использовать инструменты, такие как Prometheus, Grafana, cAdvisor, которые предоставляют метрики и визуализацию состояния контейнеров.
Как Docker влияет на производительность приложения?
Контейнер — изолированный процесс, который разделяет ядро хоста. Накладные расходы зависят от сети, файловой системы, лимитов ресурсов и среды запуска, поэтому влияние на конкретную нагрузку нужно измерять.
Вопросы на собеседовании: как построить честный ответ
Ниже — не готовая история, а варианты структуры ответа. Используйте только те пункты, которые соответствуют вашему реальному опыту: назовите контекст задачи, свои действия, ограничения и результат. Если с инструментом работала другая команда, прямо отделите её ответственность от своей.
Как вы решали проблемы сбоев в работе контейнеров?
Расскажите о конкретном сбое и последовательности диагностики: проверка статуса контейнера, docker logs, docker inspect, метрик, healthcheck, сети, volumes и лимитов ресурсов. Завершите ответ причиной сбоя и тем, как предотвратили повторение. Если такого случая не было, опишите знакомый вам порядок диагностики как теоретический алгоритм.
Какие типичные проблемы вы сталкивались при использовании Docker в проектах?
Выберите одну или две проблемы, с которыми действительно сталкивались: различия окружений, неверные переменные, права на volume, нехватка памяти, healthcheck или сеть. Например, внутри Compose приложение обращается к БД по имени сервиса и внутреннему порту, а с хоста — через опубликованный порт на localhost. Объясните, как нашли и исправили проблему.
Как вы масштабировали приложение, если работали с Kubernetes?
Опишите только свою зону ответственности. Например: «Deployment и Service поддерживала platform-команда, а я проверял логи Pod'ов, менял согласованные переменные окружения или тег образа и контролировал rollout». Если самостоятельно настраивали replicas, requests/limits, autoscaling или балансировку, назовите конкретные параметры и наблюдаемый результат. Не приписывайте себе настройку кластера, если ей занималась другая команда.
Как ответить, если с Kubernetes не работали?
Скажите об этом прямо и расскажите о ближайшем реальном опыте. Если масштабировали сервис без Kubernetes, можно описать профилирование, устранение узких мест, запуск дополнительных реплик и балансировку через Nginx. Если нагрузка оставалась небольшой, корректный ответ: «Горизонтальное масштабирование проекту не требовалось; я понимаю общий подход, но в production его не настраивал».
Как вы решали проблемы совместимости между окружениями разработки и продакшена при использовании Docker?
Назовите реальные меры, которые использовали: единый Dockerfile, Compose для локальных зависимостей, фиксированные версии образов, одинаковые команды запуска и проверка конфигурации в CI. Безопасный пример: в репозитории хранится только несекретный .env.example, а реальные .env и секреты передаёт среда развёртывания или secret manager.
Какие инструменты мониторинга и логирования Docker вы предпочитаете и почему?
Перечисляйте только инструменты, которыми пользовались лично, и поясняйте свою задачу. Например: Prometheus собирал метрики, Grafana показывала dashboards и alerts, а Elasticsearch/Logstash/Kibana использовались для поиска по логам. Если только читали готовые dashboards и логи, так и сформулируйте.
Как обновляли образы в production?
Если работали с Kubernetes, можно описать реальный rolling update Deployment: новый тег образа, постепенная замена Pod'ов, maxUnavailable/maxSurge, readiness probes, наблюдение за rollout и rollback при ошибке. Не называйте это canary deployment, если новая версия не получала отдельно ограниченную долю трафика. Если процесс обновления выполняла platform-команда, опишите только свои действия — например, подготовку образа и проверку приложения после выкладки.
Каков был ваш опыт в управлении конфигурациями и переменными окружения в контейнерах?
Расскажите, где в вашем проекте хранилась несекретная конфигурация, как передавались секреты, кто менял значения и как проверялись обязательные переменные при старте приложения. Не показывайте реальные секреты и не утверждайте, что использовали secret manager, если работали только с переменными окружения.
Какие преимущества вы заметили при использовании Docker в тестировании и развертывании приложений?
Приведите наблюдаемый результат из своего проекта: одинаковый запуск локально и в CI, изоляция зависимостей, воспроизводимый тестовый стенд или более предсказуемая доставка. Масштабирование не является автоматическим преимуществом одного Docker — для него нужна отдельная инфраструктура.
Какие были ваши подходы к оптимизации размера Docker-образов и уменьшению потребления ресурсов?
Выберите применявшиеся у вас приёмы и добавьте измеримый результат, если он есть: подходящий минимальный базовый образ, multi-stage build, .dockerignore, воспроизводимая установка зависимостей и удаление build-файлов из финального образа. Alpine подходит не всегда: для Python-пакетов с нативными зависимостями Debian slim может оказаться меньше итогового результата и проще в сборке. Не заявляйте конкретное уменьшение размера без замеров.