Отримати змінну навколишнього середовища від контейнера Docker


124

Який найпростіший спосіб отримати змінну середовища з контейнера docker, який не був задекларований в Dockerfile ?

Наприклад, змінна середовища, яка була встановлена ​​через якийсь docker exec container /bin/bashсеанс?

Я можу зробити docker exec container env | grep ENV_VAR, але я вважаю за краще щось, що просто повертає значення.

Я намагався використовувати docker exec container echo "$ENV_VAR", але заміна, здається, відбувається поза контейнером, тому я не отримую env var з контейнера, а навпаки env var з власного комп'ютера.

Дякую.


Чи є причина, чому хочеться не використовувати env та grep?
aisbaa

Мені просто потрібна цінність. Якщо я правильно розумію, мені потрібно проаналізувати вихід греп-дзвінка, і я вважаю за краще цього уникати.
Citronen

Я думав, що змінна, встановлена ​​в сесії exec, не впливає на первинний процес або наступні сеанси виконання?
Пол Бекотт

Відповіді:


137

Правильний спосіб запуску echo "$ENV_VAR"всередині контейнера, щоб заміна змінної відбувалася в контейнері:

docker exec <container_id> bash -c 'echo "$ENV_VAR"'

4
Зверніть увагу, що всі ці відповіді залежать від якоїсь оболонки. Я не в змозі отримати ENV-змінні із виконаним зображенням та базовим зображенням нуля.
Річард

docker run --rm -it CONTAINER bash -c 'echo "$MY_ENV_VAR"'
Генрік

Я отримую помилку "Помилка: Немає такого контейнера: контейнер". Я виконую команду після входу через SSH.
kunwar nitesh

1
@kunwarnitesh: Вам потрібно замінити "контейнер" на ім'я контейнера, над яким ви хочете працювати.
jwodder

1
Зробіть containerслово таким, щоб люди зрозуміли, що це змінна
Anwar

117

Щоб переглянути всі змінні env:

docker exec container env

Щоб отримати його:

docker exec container env | grep VARIABLE | cut -d'=' -f2

Моє запитання говорить, що я вважаю за краще не їхати цим маршрутом. Крім того , наступне запитання: docker exec container envа docker exec -it container /bin/bashпотім envвиплюнути різні речі. Чому?
Citronen

А-а ... можливо, саме таким чином я будую зображення
докера,

2
Гм, набагато важче зараз. Спробуйте docker inspect container.
aisbaa

docker inspect containerздається, має таке ж обмеження. Якщо я створюю змінну середовища після запуску контейнера, він не відображається у виклику до docker inspect(у розділі env).
Citronen

Я вважаю, що це краща відповідь, ніж прийнята на даний момент відповідь. У нас є, наприклад, кілька контейнерів, які не підтримуються bashкомандою alpine-node. Тож використання exec container bash -c "echo $ENV_VAR"не працює. Використання exec container envтворів для мого випадку. Використання exec container printenvтакож працює.
rahmatns

78

Ви можете використовувати printenv VARIABLEзамість /bin/bash -c 'echo $VARIABLE. Це набагато простіше, і він не виконує заміну:

docker exec container printenv VARIABLE

7
Це має бути остаточною відповіддю
Кі Джей

5
або просто printenvдля друку всіх змінних.
naXa

Це працює навіть для kubernetes: kubectl exec pod-name printenv MY_VARIABLE.
Тебу

58

Недоліком використання docker execє те, що він вимагає запущеного контейнера, тому docker inspect -fможе бути корисним, якщо ви не впевнені, що контейнер працює.

Приклад №1. Виведіть список змінних середовища проміжків середовища у вказаному контейнері:

docker inspect -f \
   '{{range $index, $value := .Config.Env}}{{$value}} {{end}}' container_name

вихід буде виглядати приблизно так:

ENV_VAR1=value1 ENV_VAR2=value2 ENV_VAR3=value3

Приклад №2. Виведіть кожен env var у новий рядок та grepпотрібні елементи, наприклад, параметри контейнера mysql можна отримати так:

docker inspect -f \
    '{{range $index, $value := .Config.Env}}{{println $value}}{{end}}' \
    container_name | grep MYSQL_

виведе:

MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=supersecret
MYSQL_USER=demo
MYSQL_DATABASE=demodb
MYSQL_MAJOR=5.5
MYSQL_VERSION=5.5.52

Приклад №3. Давайте модифікуємо приклад вище, щоб отримати вигідний вихід, який можна безпосередньо використовувати у ваших сценаріях:

docker inspect -f \
   '{{range $index, $value := .Config.Env}}export {{$value}}{{println}}{{end}}' \
   container_name | grep MYSQL

виведе:

export MYSQL_PASSWORD=secret
export MYSQL_ROOT_PASSWORD=supersecret
export MYSQL_USER=demo
export MYSQL_DATABASE=demodb
export MYSQL_MAJOR=5.5
export MYSQL_VERSION=5.5.52

Якщо ви хочете зануритися глибше, перейдіть до документації щодо тексту / шаблону Go з усіма деталями формату.


1
це найкраща відповідь. Я думаю, це має бути відповідь на окреме запитання (коли контейнер вниз)
Микола Кондратенко

Це єдина відповідь, яка працювала на мене. docker execзавжди говорив, що мій контейнер не знаю.
Доброї ночі Nerd Pride

7

Жоден з наведених вище відповідей не показує, як витягти змінну з не запущеного контейнера (якщо ви використовуєте echoпідхід run, ви не отримаєте жодного результату).

Просто runз printenvтаким чином:

docker run --rm <container> printenv <MY_VAR>

(Зауважте, що docker-composeзамість dockerроботи теж)


дуже прямо! Я погодився з таким підходом.
opncow

або просто printenvдля друку всіх змінних.
naXa


0

Відповідь @ aisbaa працює, якщо вам все одно, коли оголошена змінна середовище. Якщо ви хочете, щоб змінна середовище, навіть якщо вона була оголошена всередині exec /bin/bashсеансу, використовуйте щось на зразок:

IFS="=" read -a out <<< $(docker exec container /bin/bash -c "env | grep ENV_VAR" 2>&1)

Це не дуже красиво, але це робить роботу.

Щоб потім отримати значення, використовуйте:

echo ${out[1]}

Дивіться відповідь jwodder.
Citronen

0

Ця команда перевіряє середовище процесів стека докера в хості:

pidof   dockerd containerd containerd-shim | tr ' ' '\n' \
      | xargs -L1 -I{} -- sudo xargs -a '/proc/{}/environ' -L1 -0

0

Ми можемо модифікувати entrypointне запущений контейнер за допомогою docker runкоманди.

Приклад показує змінну середовища PATH:

  1. Використання bashта echo: Ця відповідь стверджує, що echoне дасть жодного результату, що є неправильним.

    docker run --rm --entrypoint bash <container> -c 'echo "$PATH"'
  2. використовуючи printenv

    docker run --rm --entrypoint printenv <container> PATH
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.