Docker для начинающих: полное руководство по контейнеризации
Docker произвёл революцию в мире системного администрирования и разработки. Контейнеризация позволяет упаковать приложение со всеми зависимостями в изолированную среду, которая одинаково работает на любом сервере. В этом руководстве мы разберём Docker от установки до продвинутых сценариев использования — на понятных практических примерах.
Что такое Docker и чем контейнеры отличаются от виртуальных машин?
Docker — это платформа контейнеризации, которая позволяет запускать приложения в изолированных средах (контейнерах). В отличие от виртуальных машин, контейнеры не эмулируют оборудование — они используют ядро хост-системы, что делает их невероятно лёгкими и быстрыми.
- Виртуальная машина: полная ОС + гипервизор, запуск минуты, объём гигабайты
- Контейнер Docker: только приложение + зависимости, запуск секунды, объём мегабайты
Ключевые понятия Docker:
- Образ (Image) — шаблон, из которого создаются контейнеры. Только для чтения.
- Контейнер (Container) — запущенный экземпляр образа. Изолированный процесс.
- Dockerfile — текстовый файл с инструкциями для сборки образа.
- Docker Hub — публичный реестр образов (аналог GitHub для контейнеров).
- Volume — механизм хранения данных, которые переживают перезапуск контейнера.
Как установить Docker на Debian и Ubuntu?
Установка Docker на Debian/Ubuntu из официального репозитория:
# Удаляем старые версии
apt remove -y docker docker-engine docker.io containerd runc
# Устанавливаем зависимости
apt update
apt install -y ca-certificates curl gnupg lsb-release
# Добавляем GPG-ключ Docker
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
# Добавляем репозиторий
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian $(lsb_release -cs) stable" > \
/etc/apt/sources.list.d/docker.list
# Устанавливаем Docker
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Добавляем пользователя в группу docker, чтобы не использовать sudo:
usermod -aG docker $USER
# Перелогиньтесь для применения
newgrp docker). Иначе получите ошибку «Permission denied».Какие основные команды Docker нужно знать?
Вот набор команд, которые вы будете использовать ежедневно:
# Запуск контейнера
docker run -d --name my-nginx -p 8080:80 nginx
# Просмотр запущенных контейнеров
docker ps
# Все контейнеры (включая остановленные)
docker ps -a
# Логи контейнера
docker logs my-nginx
docker logs -f my-nginx # в реальном времени
# Выполнение команды внутри контейнера
docker exec -it my-nginx bash
# Остановка и запуск
docker stop my-nginx
docker start my-nginx
# Удаление контейнера
docker rm my-nginx
# Удаление всех остановленных контейнеров
docker container prune
Работа с образами
# Поиск образов на Docker Hub
docker search postgres
# Загрузка образа
docker pull postgres:16
# Список локальных образов
docker images
# Удаление образа
docker rmi postgres:16
# Удаление всех неиспользуемых образов
docker image prune -a
Ctrl+P, затем Ctrl+Q. Или запускайте контейнер в режиме демона с флагом -d.Как создать собственный образ с помощью Dockerfile?
Dockerfile — это рецепт сборки вашего образа. Каждая инструкция создаёт слой, который кешируется при последующих сборках:
# Файл: Dockerfile
FROM python:3.12-slim
# Метаданные
LABEL maintainer="admin@example.ru"
# Рабочая директория
WORKDIR /app
# Копируем зависимости отдельно для кеширования
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Копируем код приложения
COPY . .
# Переменные окружения
ENV FLASK_APP=app.py
ENV FLASK_ENV=production
# Открываем порт
EXPOSE 5000
# Команда запуска
CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]
Сборка и запуск:
docker build -t my-flask-app:1.0 .
docker run -d -p 5000:5000 --name flask my-flask-app:1.0
Лучшие практики для Dockerfile
- Используйте
slimилиalpineбазовые образы для уменьшения размера - Копируйте requirements.txt отдельно от кода для кеширования слоёв
- Комбинируйте команды RUN через
&&для уменьшения количества слоёв - Используйте
.dockerignoreдля исключения ненужных файлов - Не запускайте процессы от root — создавайте отдельного пользователя
Как работать с Docker Compose для многоконтейнерных приложений?
Docker Compose позволяет описать все сервисы приложения в одном YAML-файле и управлять ими как единым целым:
# docker-compose.yml
services:
web:
build: .
ports:
- "8080:5000"
environment:
- DATABASE_URL=postgresql://app:secret@db:5432/myapp
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d myapp"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
pgdata:
# Запуск всех сервисов
docker compose up -d
# Просмотр статуса
docker compose ps
# Логи конкретного сервиса
docker compose logs -f web
# Остановка
docker compose down
# Остановка с удалением томов
docker compose down -v
Как управлять данными через Docker Volumes?
Контейнеры эфемерны — при удалении все данные внутри теряются. Volumes решают эту проблему:
# Создание именованного тома
docker volume create mydata
# Запуск с примонтированным томом
docker run -d -v mydata:/var/lib/postgresql/data postgres:16
# Bind mount (монтирование директории хоста)
docker run -d -v /host/path:/container/path nginx
# Список томов
docker volume ls
# Информация о томе
docker volume inspect mydata
# Очистка неиспользуемых томов
docker volume prune
Как настроить сеть между контейнерами?
Docker предоставляет несколько драйверов сети:
- bridge — сеть по умолчанию, контейнеры общаются через IP
- host — контейнер использует сеть хоста напрямую
- none — полная изоляция от сети
- overlay — для Docker Swarm, связывает контейнеры на разных хостах
# Создание пользовательской сети
docker network create --driver bridge mynet
# Запуск контейнеров в одной сети
docker run -d --name db --network mynet postgres:16
docker run -d --name app --network mynet my-app
# В пользовательской сети контейнеры доступны по имени:
# app может обращаться к db по адресу "db:5432"
Как очищать Docker от мусора и экономить дисковое пространство?
Docker быстро накапливает гигабайты неиспользуемых данных. Регулярная очистка обязательна:
# Размер, занимаемый Docker
docker system df
# Полная очистка (осторожно!)
docker system prune -a --volumes
# Выборочная очистка
docker container prune # остановленные контейнеры
docker image prune -a # неиспользуемые образы
docker volume prune # неиспользуемые тома
docker network prune # неиспользуемые сети
docker system prune -a --volumes удаляет ВСЕ неиспользуемые данные, включая тома. На production-сервере используйте выборочную очистку.Как обеспечить безопасность контейнеров Docker?
Базовые правила безопасности:
- Не запускайте контейнеры от root: используйте директиву
USERв Dockerfile - Сканируйте образы:
docker scout cves my-image - Ограничивайте ресурсы:
--memory=512m --cpus=1.0 - Используйте read-only файловую систему:
--read-only - Не монтируйте Docker socket в контейнеры без крайней необходимости
- Обновляйте базовые образы регулярно для закрытия уязвимостей
# Пример безопасного запуска
docker run -d \
--name secure-app \
--user 1000:1000 \
--read-only \
--tmpfs /tmp \
--memory=256m \
--cpus=0.5 \
--security-opt=no-new-privileges \
my-app:latest
Как использовать Docker в CI/CD пайплайне?
Docker идеально вписывается в процесс непрерывной доставки. Типичный пайплайн:
- Разработчик пушит код в Git
- CI-система собирает Docker-образ через
docker build - Образ тегируется номером версии и пушится в реестр
- CD-система разворачивает новый образ на production
# Пример для GitHub Actions
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build and push
run: |
docker build -t registry.example.ru/app:${{ github.sha }} .
docker push registry.example.ru/app:${{ github.sha }}
Какие типичные ошибки допускают новички и как их избежать?
Топ ошибок при работе с Docker:
- Хранение данных внутри контейнера — при удалении контейнера всё потеряется. Используйте volumes.
- Использование тега latest — вы не знаете, какая версия запущена. Всегда указывайте конкретную версию.
- Большие образы — используйте multi-stage builds и slim-образы.
- Секреты в Dockerfile — не хардкодьте пароли. Используйте Docker secrets или переменные окружения.
- Игнорирование логов — настройте log driver и ограничьте размер логов.
Заключение: Docker как основа современной инфраструктуры
Docker — это не просто инструмент, а новая парадигма работы с приложениями. Контейнеризация устраняет проблему «у меня на машине работает», ускоряет деплой с часов до секунд и позволяет масштабировать сервисы горизонтально. Начните с простых контейнеров, освойте Docker Compose для многокомпонентных приложений, и вы уже не сможете представить работу без Docker. Если вашей компании нужна помощь с контейнеризацией инфраструктуры — специалисты АйТи Фреш готовы помочь.
Документация: Docker Official Docs, Docker Hub
Часто задаваемые вопросы
Что делать при ошибке Permission denied при запуске docker?
После добавления пользователя в группу docker командой usermod -aG docker $USER необходимо перелогиниться в системе. Альтернатива — выполнить newgrp docker в текущей сессии. Без этого группа не подхватится и команды docker будут требовать sudo.
Как выйти из контейнера Docker без его остановки?
Нажмите комбинацию Ctrl+P, затем Ctrl+Q. Это отсоединит терминал от контейнера, но контейнер продолжит работать в фоне. Альтернативно, запускайте контейнеры с флагом -d (detached mode).
Чем Docker отличается от виртуальной машины?
Docker-контейнеры используют ядро хост-системы и не эмулируют оборудование, поэтому запускаются за секунды и занимают мегабайты. Виртуальные машины включают полную ОС с гипервизором, запускаются минуты и занимают гигабайты. Контейнеры менее изолированы, но значительно эффективнее по ресурсам.
Как правильно хранить данные в Docker, чтобы они не пропали?
Используйте Docker Volumes — именованные тома, которые сохраняются при удалении контейнера. Создайте том командой docker volume create mydata и монтируйте его при запуске: docker run -v mydata:/data. Для production предпочтительны именованные тома, а не bind mounts.
Какой базовый образ выбрать для Dockerfile?
Для Python — python:3.12-slim, для Node.js — node:20-alpine, для общего назначения — debian:bookworm-slim. Alpine-образы самые маленькие (5 МБ), но могут вызывать проблемы совместимости. Slim-образы — оптимальный баланс между размером и совместимостью.
Как ограничить ресурсы контейнера Docker?
При запуске используйте флаги --memory=512m для ограничения памяти и --cpus=1.0 для ограничения CPU. В Docker Compose — секция deploy.resources.limits. Ограничение ресурсов предотвращает ситуацию, когда один контейнер забирает все ресурсы хоста.
ООО «АйТи Фреш» возьмёт это на себя
Не хватает времени или своих специалистов — мы настроим, оптимизируем и возьмём вашу IT-инфраструктуру на постоянное сопровождение. Работаем с юридическими лицами в Москве и регионах. Собственный дата-центр, команда из 8 серверов Dell Xeon Platinum 8280 на базе МТС.