Как добавить переменные в контейнер Podman - Академия Selectel

Как добавить переменные в контейнер Podman

Тирекс
Тирекс Самый зубастый автор
2 апреля 2026

Учимся работать с переменными окружения в Podman удобно, гибко и безопасно.

Изображение записи

Когда мы запускаем контейнер, в большинстве случаев предварительно нужно указать настройки: порт, пароль, режим работы, адрес базы и т. д. Зачастую такие параметры жестко прописывают в самом коде, но это плохой стиль и вообще идея так себе. В будущем вы можете «затроить» и все это слить в git-репозиторий. А как мы знаем, хранить чувствительные данные в там нельзя.

Удобнее и гибче использовать переменные окружения. Те самые, которые environment variables. С помощью переменных можно настраивать поведение контейнера, использовать разные конфигурации (dev/stage/prod), безопасно передавать чувствительные данные. Как видите, одни плюсы.

Работа с переменными в Podman строится практически так же, как в Docker. Есть некоторые нюансы, но о них расскажу чуть позже. Сейчас давайте потыкаем на практике и посмотрим, что же происходит.

Автор статьи — Роман Шубин, CTO и автор Telegram-канала Bash Days.

Вся база

Создаем файл app.py:


      import os

 name = os.getenv("APP_NAME", "Unknown App")
 print(f"Hello from {name}!")

И рядом файл Containerfile:


      FROM python:3.11-slim

 WORKDIR /app
 COPY app.py .

 CMD ["python", "app.py"]

Собираем образ:


      podman build -t myapp .

Проверяем, все ок:

Вывод команды podman images в терминале. В списке образов отображается локальный образ localhost/myapp с тегом latest, созданный 10 секунд назад.

Теперь самое интересное — давайте передадим переменную APP_NAME в контейнер:


      podman run --rm -e APP_NAME="Podman Demo" myapp

В консоли получаем Hello от переменной, как и должно быть:

Скриншот терминала: запуск контейнера с передачей переменной через флаг -e APP_NAME='Podman Demo'. Вывод программы: Hello from Podman Demo!

В большинстве случаев это развязывает руки и делает весь процесс универсальным. Если же переменную не передать, то получим сообщение по умолчанию, уже от Unknown App, как мы указали при создании файла app.py:

Скриншот терминала: запуск контейнера myapp без передачи переменных. Программа выводит текст по умолчанию: Hello from Unknown App!

Хорошо, первый этап погружения успешно пройден.

Передача переменных через файл .env

Тут все прямо как в Docker!


      podman run --rm --env-file .env myapp
Использование флага --env-file .env в команде podman run. Контейнер считывает настройки из файла и выводит: Hello from Bashdays!

Через параметр, --env-file я передал файл .env, в котором у меня содержится набор нужных переменных:


      APP_NAME="Podman Demo"
HTTP_PORT=8080
LOGIN=123456789
PASSWORD=pa$$w0rd

С таким подходом нам не нужно раздувать командную строку кишкой из переменных — прописываем все необходимое в этот файл и затем просто подкидываем его в контейнер.

Не забываем в .gitignore добавить исключение для .env файлов. Ну а чтобы прям уж профессионально сделать, создаем рядом env.example и забиваем его теми же переменными, но тестовыми. Такой файл можно запушить в репозиторий. Он будет служить шаблоном для людей, которые захотят развернуть контейнер.

Переменные можно переопределять:


      podman run --env-file .env -e APP_NAME=true myapp
Скриншот терминала: комбинирование --env-file и флага -e. Демонстрация того, как значение -e перекрывает настройки из файла.

Приоритет отдается переменной, которую указали через командную строку. Хотя в файле .env переменная APP_NAME существует и конкретно задана. Прям все, как в Ansible с extra-vars. Кто в курсе, тот в курсе.

Quadlet

Его мы подробно разобрали в статье «Healthcheck инструментами Podman», так что детали и теорию опущу.

В файл с юнитом, например /etc/containers/systemd/demo.container, добавляем:


      [Container]
Environment=APP_NAME=QuadletApp 
Environment=APP_ENV=production 
Environment=DEBUG=false

Проверяем:


      podman exec 23828685bd1b env
Вывод команды podman exec env для контейнера, запущенного через Quadlet. Видны переменные APP_ENV=production и APP_NAME=QuadletApp.

Все отлично: переменные, указанные в юните, успешно передались. Это полный аналог команды:


      podman run -e APP_NAME=QuadletApp -e APP_ENV=production -e DEBUG=false demo

Но опять же логичнее использовать файл, особенно если переменных много. В юните это выглядит так:


      EnvironmentFile=%h/dev/app/.env

%h — это домашний каталог пользователя.

Тут главное не ошибиться в путях. Так работать не будет:


      EnvironmentFile=.env

Переменные в юните можно переопределить:


      [Container] 
 EnvironmentFile=%h/dev/app/.env
 Environment=DEBUG=true

DEBUG=true перезапишет значение из файла.

Нюанс. Если прав на файл с переменными не хватит, то в контейнер ничего не передастся. Тут лучше сразу на берегу этот момент проверять либо смотреть по логам, чтобы варнингов и алертов не было. Особенно это критично с SELinux, он здорово палки в колеса вставляет. Это не страшно, но внимательным стоит быть.

Нормальная работа с секретами в Podman

Когда вы передаете секреты через переменные, их можно увидеть через inspect. Секреты могут попасть в логи, а это уже такое себе.

Podman Secrets — это отдельное хранилище чувствительных данных, которые не передаются как env-переменные, а монтируются в контейнер как файл. Внутри контейнера он обычно лежит здесь:


      /run/secrets/<имя>

Создаем секрет:


      echo "superpassword" | podman secret create db_password -

Проверяем, что он есть. В данном примере в столбце NAME видим наш db_password:

Вывод команды podman secret ls, подтверждающий создание секрета с именем db_password и драйвером типа file.

Запускаем контейнер с секретом:


      podman run --rm --secret db_password alpine cat /run/secrets/db_password

В результате видим superpassword:

Скриншот терминала: чтение файла секрета внутри контейнера alpine. Вывод отображает значение секрета: superpassword.

Если сделать inspect, то мы ничего интересного не увидим — наш суперсекретный пароль не будет раскрыт. По-моему, это отличная фича. Когда я о ней узнал, радовался как ребенок.

Команда podman inspect, показывающая метаданные секрета db_password в формате JSON внутри терминала.

Внутри приложения можно дергать эти секреты, например на Python:


      DB_PASSWORD = open("/run/secrets/db_password").read().strip()

Это не env-переменная, она доступна только внутри контейнера и только для чтения. Путь хранения файла с секретами можно переопределить:


      --secret db_password,target=/tmp/pass

Удаление секрета:


      podman secret rm db_password

Внутри Quadlet-юнита это выглядит так:


      [Container] 
 Secret=db_password

А что не нужно помещать в секреты? Логичнее туда не пихать: порты, режимы (debug и т. п.), IP, имена сервисов. В общем, все, что не секретное. Не засоряйте хламом, потом проще будет ориентироваться. Хлам храни в .env-файлах.

  • env-переменные → для конфигурации,
  • secrets → для чувствительных данных.

В Docker такое тоже было, но если память не изменяет, работало оно только в Swarm. А Swarm, как мы знаем — мертвое легаси, которое лучше не трогать. Так что если у вас есть на борту Podman, у вас развязаны руки. Интересных фич — прям вагон и телега. Главное — о них от кого-то узнать. Например, от меня.

Остатки

Пройдемся по тому, что не уместилось в предыдущие разделы.

Использование переменных в CMD

Можно использовать переменные прямо в CMD или ENTRYPOINT.


      CMD ["sh", "-c", "echo Running on port $PORT"]

Но тут есть еще один нюанс: shell-форма будет работать, а exec python — нет. Если знаете, почему, расскажите в комментариях.

Переменные на этапе сборки (ARG vs ENV)


      ARG VERSION=2.0
ENV APP_VERSION=$VERSION

ARG будет использоваться только при сборке контейнера. ENV — внутри контейнера.


      podman build --build-arg VERSION=2.0 .

Наследование переменных хоста

Можно прокинуть переменную прямо из системы:


      export APP_ENV=production
podman run -e APP_ENV myapp

Переменные в Compose сегодня рассматривать не будем, это тема следующей статьи.

Best practices

  • не храним секреты в .env,
  • используем EnvironmentFile для systemd,
  • разделяем env по окружениям (.env.dev, .env.prod),
  • не хардкодим значения в Containerfile,
  • проверяем через Podman inspect,
  • пользуемся Podman secrets.

Подведем итоги

На первый взгляд, переменные в Podman — это просто -e и .env, но на практике вокруг них строится вся конфигурация контейнера. Чем раньше вы начнете правильно работать с ними, тем проще вам будет масштабировать и поддерживать свои сервисы.

The End!