Podman запускает контейнеры без постоянного демона и умеет работать от обычного пользователя. Но при переносе проекта с Docker почти сразу возникает вопрос: что делать с готовым compose-файлом, в котором описаны сервисы, тома и сети. Переписывать всё на длинные команды podman run не нужно. Есть утилита podman-compose и встроенная обёртка podman compose, которая вызывает выбранный провайдер. Оба варианта читают тот же YAML, но различия в поведении стоит проверить до вывода нагрузки в работу.

Два способа запустить compose-файл

podman-compose — отдельная утилита на Python, её ставят пакетом из репозитория. Команда podman compose входит в сам Podman и только передаёт аргументы внешнему провайдеру. Список провайдеров задаётся в containers.conf в секции [engine], параметр compose_providers. По умолчанию Podman ищет docker-compose, а затем podman-compose. Если на машине остался Docker CLI, легко получить неожиданный результат: команда выполнится, но контейнеры окажутся в Docker. Поэтому сначала выясняем, кто именно отвечает на вызов.

sudo apt install podman podman-compose
podman --version
podman-compose --version
podman compose version

Последняя команда показывает выбранный провайдер. Если в выводе упомянут docker-compose, провайдера задают явно в конфигурации или удаляют Docker CLI с узла, где он не нужен. Смешивать два движка на одном хосте можно, но диагностика усложняется: podman ps не увидит контейнеры Docker, и наоборот.

Подготовка compose-файла

Большинство ключей переносится без правок: image, ports, volumes, environment, healthcheck, restart. Именованные тома лучше не заменять привязкой к каталогу хоста: у rootless-контейнера другой набор UID, и права на файлы могут не совпасть. Для SELinux добавьте суффикс :Z к точке монтирования, иначе процесс получит отказ доступа.

services:
  web:
    image: docker.io/library/nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - html:/usr/share/nginx/html:Z
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost/"]
      interval: 30s
      timeout: 5s
      retries: 3
    restart: unless-stopped
volumes:
  html:

Порт 80 внутри контейнера — нормальный приём, но публиковать его в rootless-режиме нельзя без отдельной настройки. Наружу отдаём 8080 и ставим впереди обратный прокси, либо разрешаем непривилегированные порты через sysctl. Второй путь проще для домашнего сервера, первый безопаснее для машины с доступом из сети.

Запуск и повседневные команды

Дальше работа почти не отличается от привычной. Обёртка поднимает проект в фоне, показывает состояние, отдаёт логи и запускает команду внутри контейнера. podman-compose дополнительно создаёт pod на проект, поэтому в podman pod ps виден общий контейнер инфраструктуры.

podman compose up -d
podman compose ps
podman compose logs -f web
podman compose exec web sh

Остановка с down удаляет контейнеры и сети, но сохраняет именованные тома. Ключ -v удаляет и их, поэтому применять его стоит осознанно. Перед запуском полезно выполнить podman compose config: команда раскрывает переменные окружения и показывает итоговый YAML, что помогает поймать опечатку в имени тома или незаполненную переменную.

Rootless, порты и SELinux

Проверьте диапазоны subordinate UID и GID в /etc/subuid и /etc/subgid. Если пользователь создан без них, Podman не сможет отобразить владельцев файлов внутри контейнера, и вы увидите странные числовые идентификаторы. Исправить это можно через usermod --add-subuids и --add-subgids, после чего полезно перезапустить сессию.

grep "$USER" /etc/subuid /etc/subgid
sudo sysctl net.ipv4.ip_unprivileged_port_start=80
echo 'net.ipv4.ip_unprivileged_port_start=80' | sudo tee /etc/sysctl.d/90-podman.conf
loginctl enable-linger "$USER"

Без enable-linger пользовательские процессы завершаются после выхода из SSH, и контейнеры останавливаются вместе с ними. Для серверного сценария это обязательный шаг. Ещё одна частая проблема — файлы, созданные контейнером, принадлежат отображённому UID; не меняйте владельца рекурсивно на хосте, а проверьте настройки тома и права каталога.

Автозапуск через systemd

Старый способ с podman generate systemd считается устаревшим, в Podman 5 и новее основная ставка сделана на Quadlet. Файл с расширением .container кладут в ~/.config/containers/systemd/, systemd генерирует unit при перезагрузке конфигурации. Для проекта из нескольких сервисов добавляют общую сеть и зависимости After=.

[Unit]
Description=Nginx for site
[Container]
Image=docker.io/library/nginx:alpine
PublishPort=8080:80
Volume=html.volume:/usr/share/nginx/html:Z
AutoUpdate=registry
[Install]
WantedBy=default.target

Рядом должен лежать файл html.volume, иначе юнит не запустится. После создания выполните systemctl --user daemon-reload и запустите юнит. Параметр AutoUpdate=registry разрешает podman auto-update подтягивать новый образ; без него команда ничего не изменит. Обновление лучше ставить в таймер и проверять здоровье сервиса после каждого запуска.

Диагностика

Когда контейнер не стартует, смотрите не только логи приложения. Обёртка может скрывать причину, если ошибка произошла на этапе разбора файла или монтирования тома.

  • podman compose config — проверка синтаксиса и подстановки переменных.
  • podman inspect — состояние healthcheck и код возврата.
  • podman events — события движка за последние минуты.
  • journalctl --user — запуск через systemd и причины падения юнита.
podman compose config
podman inspect --format '{{.State.Health.Status}}' web
podman events --filter container=web --since 10m
journalctl --user -u web --no-pager -n 50

Код 127 обычно означает, что в образе нет команды из healthcheck, например wget или curl. Ошибка address already in use указывает на занятый порт: проверьте ss -ltnp. Отказ доступа к тому часто связан с SELinux или неверным владельцем каталога, а не с самим Podman.

Ограничения подхода

Compose остаётся инструментом для одного хоста. Он не планирует задачи на кластер, не переносит контейнеры между машинами и не умеет автоматически масштабировать сервис. Ключи deploy поддерживаются частично, условия depends_on обрабатываются не во всех версиях, а сборка образов может отличаться от Docker. Для разработки и небольшого сервера этого достаточно, для отказоустойчивого кластера нужен другой уровень оркестрации.

Если приложение уже описано в compose-файле, перенос на Podman занимает минуты. Начните с проверки провайдера, затем настройте rootless-порты и linger, а автозапуск переведите на Quadlet. Такой набор даёт предсказуемый сервер без демона и без лишних зависимостей.

Итог

Podman Compose — рабочий способ запускать привычные многоконтейнерные проекты без Docker. Выберите провайдера, проверьте монтирования и порты, добавьте systemd-юнит для автозапуска. Ограничения известны заранее, поэтому решение не станет сюрпризом при росте нагрузки.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте