Docker Stack Deploy не разрешает переменные среды со значениями по умолчанию, как Docker Compose.

Docker Stack Deploy не разрешает переменные среды со значениями по умолчанию, как Docker Compose.

У меня есть следующие файлы-примеры

docker-compose.yml

version: '3'
services:
  web:
    image: webapp:${VARIABLE_A:-${VARIABLE_B}}

env.conf

VARIABLE_B=123

VARIABLE_Aне установлено специально, поэтому оно должно вернуться кVARIABLE_B

Docker Compose может разрешить значение по умолчанию переменной среды, однако docker stack deployне может сделать то же самое разрешение

user@laptop:~$ docker compose --env-file ./env.conf convert

name: dockercomposetest
services:
  web:
    image: webapp:123
    networks:
      default: null
networks:
  default:
    name: dockercomposetest_default
user@laptop:~$ env $(cat ./env.conf | xargs) docker stack deploy --compose-file docker-compose.yml stack

Creating service stack_web
failed to create service stack_web: 
  Error response from daemon: 
  rpc error: 
    code = InvalidArgument desc = ContainerSpec: "webapp:${VARIABLE_B}" is not a valid repository/tag

Как вы можете видеть, при использовании docker stack deployон обнаруживает ${VARIABLE_A:-${VARIABLE_B}}переменную окружения, которая, поскольку VARIABLE_Aне установлена, должна иметь значение по умолчанию, ${VARIABLE_B}однако он не разрешает ее значение, которое является123

Очевидно, что webapp не существует, это всего лишь пример, но приведенный выше вывод ошибки должен быть таким:

user@laptop:~$ env $(cat ./env.conf | xargs) docker stack deploy --compose-file docker-compose.yml stack

Creating service stack_web
failed to create service stack_web: 
  Error response from daemon: 
  rpc error: 
    code = InvalidArgument desc = ContainerSpec: "webapp:123" is not a valid repository/tag

Почему это происходит? Есть ли какие-то обходные пути?

решение1

Для справки см. mobyDocker Stack Deploy в версии 1.13 не загружает файл .env, как это делает docker-compose up. КонкретноКомментарий от kinghuang

«Мои разработчики используют конфигурацию docker-compose для предварительной обработки проектов Docker Compose перед их передачей в развертывание стека docker. Вы можете сделать это одной строкой:

docker stack deploy -c <(docker-compose config) stack-name-here

Таким образом, все функции Docker Compose, включая обработку .env, будут полностью применены».

решение2

Обходной путь, который я в итоге применил, docker stack deploy— это envsubstзамена переменных окружения

user@laptop:~$ env $(cat ./env.conf | xargs) envsubst < ./docker-compose.yml | docker stack deploy --compose-file - stack

В документации говорится, что при использовании --compose-file -он принимает stdinфайл docker compose, поэтому по сути это сначала разрешает все переменные в , docker-compose.ymlа затем передает результат с помощью конвейера вdocker stack deploy

решение3

Вот еще один хороший способ, как вы можете преодолеть эту проблему. Вам нужно создать файл ".env" со всеми переменными, которые вы хотите добавить в среду, например: APP_NAME=Example. Затем в вашем stack-compose.yml вы можете объявить его следующим образом:

version: "3.9" 
services: 
  myservice: 
    env_file: 
      - .env

После этого необходимо выполнить следующую команду:

docker stack config -c stack-compose.yml | docker stack deploy -c - mystackname

Что вставит переменные, объявленные вами в файле .env, в stack_compose.yml следующим образом:

version: "3.9"
services:
  myservice:
    environment:
      APP_NAME: "Example"

По этой ссылкеКак передать переменные env в стек Docker Swarm

Вы найдете очень хорошее объяснение, как это сделать. У меня была та же проблема, и я ее преодолел таким образом. С уважением

Связанный контент