Разбираем ключевые аспекты работы с контейнерами Docker на Ubuntu 24.04 на VPS: от запуска до настройки сетей и томов. В статье — управление контейнерами, запуск в пользовательской изолированной сети, настройка томов, мониторинг потребления ресурсов.
Жизненный цикл контейнера
Основная команда docker run создаёт и запускает контейнер из образа. Рассмотрим пример для веб-сервера Nginx:
docker run -d --name my_nginx -p 8080:80 -v nginx_data:/etc/nginx nginx:alpine
Docker проверит локальный кеш образов и, если образ отсутствует, автоматически скачает его из Docker Hub.
Ключевые элементы команды и их назначение:
- -d (detached mode) — запуск в фоновом режиме, что освобождает терминал;
- --name — уникальный идентификатор контейнера вместо автоматической генерации;
- -p 8080:80 — проброс портов (хост:контейнер), где 8080 — порт хоста Ubuntu, 80 — порт контейнера;
- -v nginx_data:/etc/nginx — монтирование тома для сохранения конфигов после удаления контейнера;
- nginx — Docker-образ; если нужен минималистичный образ, то можно использовать nginx:alpine (его размер в несколько раз меньше официального образа nginx).
В Ubuntu 24.04 важно различать типы драйверов, которые использует Docker. По умолчанию для хранения слоёв образов и файловой системы контейнеров применяется драйвер overlay2. Он работает поверх таких файловых систем, как ext4, xfs и btrfs, и не используется для управления томами.
Для томов Docker использует отдельный механизм. Стандартный драйвер томов — local, но можно выбрать и другой (например, zfs, nfs или btrfs). Чтобы использовать нестандартный драйвер по умолчанию, необходимо указать его в конфигурации демона Docker — в файле:
/etc/docker/daemon.json
Если вы хотите применить другой драйвер только для одного конкретного тома, создайте его заранее с указанием нужного драйвера:
docker volume create --driver=zfs my_volume
Только после этого можно использовать том при запуске контейнера. Это важно для совместимости и корректной работы хранилища данных.
Чтобы взаимодействовать с запущенным контейнером введите:
docker exec -it my_nginx sh
Здесь:
- -it (interactive + TTY) — создаёт интерактивную сессию с псевдотерминалом;
- sh вместо bash — для минималистичных образов, которые не всегда имеют bash.
Для выхода из сессии без остановки контейнера нажмите Ctrl+P → Ctrl+Q.
Три ключевые команды для управления контейнерами:
docker stop my_nginx # мягкая остановка: SIGTERM → SIGKILL через 10 секунд
docker start my_nginx # перезапуск с сохранённой конфигурацией
docker rm my_nginx # удаление контейнера (возможно только после остановки)
Для принудительного удаления работающего контейнера используйте docker rm -f.
Важно в продакшене:
- Всегда используйте stop перед rm для корректного завершения процессов.
- Для stateful-сервисов (с сохранением состояния, например, БД) добавляйте флаг --time=30 к stop для увеличения таймаута.
Не забывайте про мониторинг ресурсов и логов. Для этого используют команду docker stats — она предоставляет мгновенные данные об использовании ресурсов контейнером:
docker stats my_nginx --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
Результат будет выведен в табличном формате:
Результат будет выведен в табличном формате. Можно отобразить следующие метрики:
- {{.Container}} — имя контейнера;
- {{.CPUPerc}} — процент использования CPU (учитываются все ядра);
- {{.MemUsage}} — объём используемой памяти в формате текущее/лимит (например: 145.3MiB/2GiB);
- {{.PIDs}} — количество процессов;
- {{.BlockIO}} — объём дисковых операций (чтение/запись).
Анализ логов:
docker logs --tail 100 -f --timestamps my_nginx
Здесь:
- --tail 100 — последние 100 строк;
- -f (follow) — потоковый вывод;
- --timestamps — метки времени для диагностики задержек.
Автоматический рестарт контейнеров при сбоях или перезагрузке хоста (--restart):
docker run -d --restart=unless-stopped --name watchdog nginx:alpine
Варианты политики:
- unless-stopped — запуск при старте системы, если контейнер не был явно остановлен;
- no — отключение автозапуска (по умолчанию);
- on-failure[:max-retries] — рестарт при ошибках с лимитом попыток;
- always — безусловный перезапуск даже после ручного stop.
Сети и тома
Настройка сетевых режимов
Docker предоставляет гибкие варианты сетевой изоляции, что важно для безопасности и производительности. Пользовательская сеть создаётся командой:
docker network create --driver=bridge --subnet=172.20.0.0/24 app_net
Детали команды:
- --driver=bridge — драйвер по умолчанию для изолированных сетей (альтернативы: macvlan, ipvlan);
- --subnet — явное задание подсети предотвращает конфликты адресов;
- --gateway=172.20.0.1 — опциональное указание шлюза;
- app_net — имя сети.
Пример запуска контейнера в пользовательской сети:
docker run -d --net=app_net --name db --ip=172.20.0.10 postgres:15
Здесь:
- --net=app_net — подключает контейнер к пользовательской сети app_net;
- --name db — присваивает контейнеру уникальное имя db;
- --ip=172.20.0.10 — статический IP-адрес в подсети сети app_net (app_net должна иметь подсеть, включающую этот адрес, адрес не должен быть занят другими контейнерами);
- postgres:15 — образ Docker из официального репозитория.
Преимущества перед сетью по умолчанию:
- автоматическое разрешение имён между контейнерами,
- изоляция трафика от других сетей Docker,
- возможность статической IP-адресации.
Управление томами и хранилищами
Тома обеспечивают сохранность данных после удаления контейнеров. Создание именованного тома:
docker volume create --driver=local \
--opt type=zfs \
--opt device=zpool/docker \
--opt o=size=10GB \
--label type=db \
db_data
Опции:
- --driver=local — драйвер локального хранилища;
- --opt type=zfs/btrfs/xfs — выбор файловой системы;
- --opt device=zpool/docker — целевое устройство или ZFS-пул (ZFS-пул уже должен быть создан);
- --opt o=size=10GB — квота дискового пространства;
- --label type=db — метка для фильтрации.
Также обязательно задать имя тома, в примере — db_data.
Теперь рассмотрим, как монтировать том db_data в контейнер и какие дополнительные опции нужно указывать. Убедитесь, что том пуст перед первым запуском, иначе могут возникнуть проблемы с правами; если же вы монтируете непустой том, проверьте владельца файлов: они должны принадлежать UID, который используется в контейнере.
Монтирование в контейнер:
docker run -v db_data:/var/lib/postgresql:rw postgres:15
Разберем каждую часть команды:
- -v db_data:/var/lib/postgresql:
- db_data — имя тома, который мы создали;
- /var/lib/postgresql — путь внутри контейнера, куда будет смонтирован том.
- Опции монтирования указывают после двоеточия. rw (read-write, чтение и запись) — режим доступа, этот режим используется по умолчанию, но здесь указан явно. Только для чтения — ro.
- postgres:15 — образ PostgreSQL 15.
В результате том db_data будет смонтирован в контейнер по пути /var/lib/postgresql. Все данные, которые PostgreSQL запишет в этот каталог, будут сохраняться в томе и останутся после удаления контейнера.
Заключение
Для промышленной эксплуатации Docker на Ubuntu 24.04:
- Сканируйте образы (docker scan) и запускайте от non-root пользователей.
- Настройте journald для централизованного сбора логов контейнеров.
- Жёстко ограничивайте ресурсы (--cpus, --memory) во избежание исчерпания.
Читайте в блоге:
- Хостинг сайта на Ubuntu 24.04 LTS: NGINX, SSL и WordPress
- Интеграция WordPress с Nginx и MariaDB на Ubuntu 24.04: от базы данных до SSL
- Автоматическая настройка VPS-сервера на Ubuntu 24.04 с помощью Cloud-init