Как использовать переменные среды compose в docker ENTRYPOINT

#docker #docker-compose

#docker #docker-compose

Вопрос:

Переменные среды, похоже, не работают ENTRYPOINT . Насколько я понимаю, форма оболочки ENTRYPOINT будет расширять ENV переменные во время выполнения, но, похоже, это не работает ENV_CONFIG_INT в примере ниже. Что я сделал не так в следующем примере?

Dockerfile

 ENTRYPOINT [ "yarn", "run", "app-${ENV_CONFIG_INT}" ]
 

Создайте yaml

 test:
    image: testimage/test:v1.0
    build:
        context: .
        dockerfile: Dockerfile
    env_file:
        - ./docker.env
    environment:
        - ENV_CONFIG_INT=1
 

Ошибка:

 error Command "app-${ENV_CONFIG_INT}" not found.
 

Замена значения статическим значением int, скажем, 1, устраняет проблему, однако я хочу, чтобы значение было динамическим во время выполнения.

Заранее спасибо.

Ответ №1:

Я бы не стал пытаться использовать переменную среды для указания команды для запуска. Удалите строку, которую вы показываете, из файла Dockerfile и вместо этого укажите command: в своем docker-compose.yml файле:

 test:
  image: testimage/test:v1.0
  build: .
  env_file:
    - ./docker.env
  command: yarn run app-1  # <--
 

Как вы заметили, форма оболочки ENTRYPOINT CMD и RUN ) будет расширять переменные среды, но вы не используете форму оболочки: вы используете форму exec, которая не расширяет переменные и не обрабатывает какие-либо другие конструкции оболочки. Если вы удалите макет JSON-массива и просто укажете плоскую команду, переменная среды будет расширена так, как вы ожидаете.

 # Without JSON layout
CMD yarn run "app-${ENV_CONFIG_INT:-0}"
 

(Я, как правило, предпочитаю указывать CMD значение ENTRYPOINT для основной команды приложения. Для этого есть две причины: его легче переопределить CMD при простом docker run вызове, и существует полезный шаблон использования ENTRYPOINT в качестве скрипта-оболочки, который выполняет некоторую начальную настройку, а затем запускает CMD .)

Комментарии:

1. Это было очень информативное спасибо. Как было предложено, если я удалю ТОЧКУ ВХОДА, не является ли стандартной практикой указывать хотя бы одну ТОЧКУ ВХОДА или CMD?

2. Предоставление значения по умолчанию CMD является хорошей практикой. Я обычно думаю о Compose command: как о переопределении, хотя в этом случае, когда для каждого контейнера требуется отдельная командная строка, это уместно.

Ответ №2:

Обычный способ гарантировать, что расширение переменной среды работает в точке входа или команде изображения, — это использовать bash — или sh — в качестве точки входа.

 version: "3.8"

services:
  test:
    image: alpine
    environment:
      FOO: "bar"
    entrypoint: ["/bin/sh", "-c", "echo ${FOO}"]
 
 $ docker-compose run test
Creating so_test_run ... done
bar
 

Другая вещь, которую вам нужно сделать, это правильно экранировать переменную среды, чтобы она не расширялась в хост-системе.