Docker Stack Deploy não resolve variáveis ​​de ambiente com valor padrão como o Docker Compose faz

Docker Stack Deploy não resolve variáveis ​​de ambiente com valor padrão como o Docker Compose faz

Eu tenho os seguintes arquivos de exemplo

docker-compose.yml

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

env.conf

VARIABLE_B=123

VARIABLE_Anão é definido de propósito, então deve voltar paraVARIABLE_B

Docker compose é capaz de resolver o valor padrão da variável de ambiente, porém docker stack deploynão consegue fazer a mesma resolução

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

Como você pode ver ao usá- docker stack deploylo, detecta ${VARIABLE_A:-${VARIABLE_B}}uma variável de ambiente que, por VARIABLE_Anão estar definida, deve ser padronizada, ${VARIABLE_B}porém não resolve seu valor, que é123

Obviamente, webapp não existe, é apenas um exemplo, mas a saída de erro acima deveria ser esta

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

Por que isso acontece? Existe alguma solução alternativa para isso?

Responder1

Para referência, veja em mobydocker stack deploy em 1.13 não carrega o arquivo .env como o docker-compose up faz. EspecificamenteComentário de Kinghuang

"Meus desenvolvedores usam a configuração do docker-compose para pré-processar projetos do Docker Compose antes de passá-los para a implantação da pilha do docker. Você pode fazer isso em uma linha com:

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

Dessa forma, todos os recursos do Docker Compose, incluindo o processamento .env, são totalmente aplicados."

Responder2

A solução alternativa que acabei fazendo docker stack deployfoi usar envsubstpara substituir env vars

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

A documentação diz que, ao usá-lo, --compose-file -ele assume stdino arquivo de composição do docker, então basicamente o que isso faz é primeiro resolver todas as variáveis ​​no arquivo docker-compose.ymle depois passar o resultado usando um canal paradocker stack deploy

Responder3

Aqui está outra boa maneira de superar esse problema. Você tem que criar um arquivo ".env" com todas as variáveis ​​que deseja adicionar ao ambiente por exemplo: APP_NAME=Example. Então no seu stack-compose.yml você pode declará-lo assim:

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

Depois disso, você deve executar o seguinte comando:

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

Que irá inserir as variáveis ​​que você declarou no arquivo .env no stack_compose.yml assim:

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

Neste linkComo passar variáveis ​​​​env na pilha docker swarm

Você encontrará uma explicação muito boa de como fazer isso. Eu tive o mesmo problema e superei dessa maneira. Cumprimentos

informação relacionada