
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_A
nã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 deploy
nã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 deploy
lo, detecta ${VARIABLE_A:-${VARIABLE_B}}
uma variável de ambiente que, por VARIABLE_A
nã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 deploy
foi usar envsubst
para 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 stdin
o arquivo de composição do docker, então basicamente o que isso faz é primeiro resolver todas as variáveis no arquivo docker-compose.yml
e 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