Arg e Env
- Args e ENV
Diferença de ARG e ENV
Diferença de ARG e ENV
Docker ARG, ENV e .env - um guia completo
Error: Docker image build failed.

Criar imagens do Docker e configurar seus aplicativos dockerizados não precisa ser uma extravagância do Google try-fail-repeat. Este artigo ajudará você a trabalhar com arquivos Docker ARG, ENV, env_file e .env com confiança.
O único pré-requisito: certifique-se de estar familiarizado com o básico do Docker.
Continue lendo e você entenderá como configurar suas imagens do Docker e aplicativos dockerizados com facilidade - com o poder das variáveis de tempo de compilação do Docker, variáveis de ambiente e modelos de composição do docker.
Equívocos frequentes
Esta é uma leitura longa e profunda. Vamos começar com algo que você pode usar agora, sem ter que ler tudo!
Aqui está uma lista de dicas fáceis :
-
O arquivo .env
é usado apenas durante uma etapa de pré-processamento ao trabalhar com arquivos docker-compose.yml. Variáveis de notação de dólar como $HI são substituídas por valores contidos em um arquivo denominado “.env” no mesmo diretório.
-
O ARGcontornar
só está disponível durante a compilação de uma imagem do Docker (RUN etc.), não depois que a imagem é criada e os contêineres são iniciados a partir dela (ENTRYPOINT, CMD). Você pode usar valores ARG para definir valores ENV para
isso.
-
Os valores ENV
estão disponíveis para contêineres, mas também comandos no estilo RUN durante a compilação do Docker, começando com a linha em que são introduzidos.
-
Se você definir uma variável de ambiente em um contêiner intermediáriouma maneira
usando bash (RUN export VARI=5 && …) ela não persistirá no próximo comando. Há
de contornar isso.
-
Um env_file*.env*
, é uma maneira conveniente de passar muitas variáveis de ambiente para um único comando em um lote. Isso não deve ser confundido com um arquivo
.
-
Definir valores ARG e ENV deixa rastroscompilações de vários estágios
na imagem do Docker. Não os use para segredos que não devem ficar por perto (bem, você meio que pode com
).
Uma visão geral
Tudo bem, vamos começar com os detalhes. O guia está dividido nos seguintes tópicos:
- O arquivo Dot-Env (.env)
- Disponibilidade ARG e ENV
- Configurando Valores ARG
- Configurando Valores ENV
- Substituindo Valores ENV
Sinta-se à vontade para pular direto para o que você precisa agora. No entanto, você obterá o melhor resultado se ler todos eles cuidadosamente.
O arquivo Dot-Env (.env)
Este é bem simples, e apenas confuso por causa de exemplos ruins e conceitos semelhantes usando o mesmo formato, soando muito parecido com ele. O importante é o ponto na frente de env - .env , não um “env_file”.
Se você tiver um arquivo chamado .env em seu projeto, ele será usado apenas para colocar valores no arquivo docker-compose.yml que está na mesma pasta. Esses são usados com o Docker Compose e o Docker Stack. Não tem nada a ver com ENV, ARG ou qualquer coisa específica do Docker explicada acima. É exclusivamente uma coisa docker-compose.yml.
Os valores no .envarquivo são escritos na seguinte notação:
VARIABLE_NAME=some value
OTHER_VARIABLE_NAME=some other value, like 5
Esses pares de chave-valor são usados para substituir variáveis de notação de dólar no arquivo docker-compose.yml. É uma espécie de etapa de pré-processamento, e o arquivo temporário resultante é usado. Esta é uma boa maneira de evitar valores de codificação permanente. Você também pode usar isso para definir os valores das variáveis de ambiente, substituindo a string, mas isso não acontece automaticamente.
Aqui está um exemplo de arquivo docker-compose.yml, baseado em valores fornecidos de um arquivo .env:
version: '3'
services:
plex:
image: linuxserver/plex
environment:
- env_var_name=${VARIABLE_NAME} # here it is
Dica: Ao trabalhar com um arquivo .env, você pode depurar seus arquivos docker-compose.yml com bastante facilidade. Basta digitar docker-compose config . Dessa forma, você verá como fica o conteúdo do arquivo docker-compose.yml depois que a etapa de substituição foi executada sem executar mais nada.
Aqui está uma pegadinha que você deve saber: variáveis de ambiente em seu host podem substituir os valores em seu arquivo .env. Leia mais aqui .
Disponibilidade ARG e ENV
Ao usar o Docker, distinguimos entre dois tipos diferentes de variáveis - ARG e ENV.
ARG também são conhecidos como variáveis de tempo de construção . Eles só estão disponíveis a partir do momento em que são 'anunciados' no Dockerfile com uma instrução ARG até o momento em que a imagem é construída. Os contêineres em execução não podem acessar valores de variáveis ARG. Isso também se aplica às instruções CMD e ENTRYPOINT que apenas informam o que o contêiner deve executar por padrão. Se você disser a um Dockerfile para esperar várias variáveis ARG (sem um valor padrão), mas nenhuma for fornecida ao executar o buildcomando, haverá uma mensagem de erro.
No entanto, os valores de ARG podem ser facilmente inspecionados após a criação de uma imagem, visualizando o valor docker historyde uma imagem. Assim, eles são uma má escolha para dados confidenciais.
As variáveis ENV também estão disponíveis durante a compilação, assim que você as introduz com uma instrução ENV. No entanto, ao contrário do ARG, eles também são acessíveis por contêineres iniciados a partir da imagem final. Os valores ENV podem ser substituídos ao iniciar um contêiner, mais sobre isso abaixo.
Aqui está uma visão geral simplificada das disponibilidades de ARG e ENV em torno do processo de criação de uma imagem do Docker a partir de um Dockerfile e da execução de um contêiner. Eles se sobrepõem, mas o ARG não pode ser usado de dentro dos contêineres.

Uma visão geral da disponibilidade de ARG e ENV.
Configurando Valores ARG
Então, você tem seu Dockerfile, que define os valores ARG e ENV. Como defini-los e onde? Você pode deixá-los em branco no Dockerfile ou definir valores padrão. Se você não fornecer um valor para as variáveis ARG esperadas que não têm um padrão, você receberá uma mensagem de erro.
Aqui está um exemplo do Dockerfile, tanto para valores padrão quanto sem eles:
ARG some_variable_name
# or with a hard-coded default:
#ARG some_variable_name=default_value
RUN echo "Oh dang look at that $some_variable_name"
# you could also use braces - ${some_variable_name}
Ao criar uma imagem do Docker a partir da linha de comando, você pode definir valores ARG usando –build-arg :
$ docker build --build-arg some_variable_name=a_value
A execução desse comando, com o Dockerfile acima, resultará na impressão da seguinte linha (entre outras):
Oh dang look at that a_value
Então, como isso se traduz em usar arquivos docker-compose.yml? Ao usar o docker-compose, você pode especificar valores para passar para ARG, em um bloco args :
(arquivo docker-compose.yml)
version: '3'
services:
somename:
build:
context: ./app
dockerfile: Dockerfile
args:
some_variable_name: a_value
Quando você tenta definir uma variável que não seja ARG mencionada no Dockerfile, o Docker reclamará.
Configurando Valores ENV
Então, como definir os valores de ENV? Voc ê pode fazer isso ao iniciar seus contêineres (e veremos isso um pouco abaixo), mas você também pode fornecer valores ENV padrão diretamente em seu Dockerfile codificando-os. Além disso, você pode definir valores padrão dinâmicos para variáveis de ambiente!
Ao construir uma imagem, a única coisa que você pode fornecer são os valores ARG, conforme descrito acima. Você não pode fornecer valores para variáveis ENV diretamente. No entanto, ARG e ENV podem trabalhar juntos. Você pode usar ARG para definir os valores padrão de ENV vars. Aqui está um Dockerfile básico, usando valores padrão codificados:
# no default value
ENV hey
# a default value
ENV foo /bar
# or ENV foo=/bar
# ENV values can be used during the build
ADD . $foo
# or ADD . ${foo}
# translates to: ADD . /bar
E aqui está um trecho de um Dockerfile, usando valores env dinâmicos na compilação:
# expect a build-time variable
ARG A_VARIABLE
# use the value to set the ENV var default
ENV an_env_var=$A_VARIABLE
# if not overridden, that value of an_env_var will be available to your containers!
Depois que a imagem é criada , você pode iniciar contêineres e fornecer valores para variáveis ENV de três maneiras diferentes , seja na linha de comando ou usando um arquivo docker-compose.yml. Todos eles substituirão quaisquer valores ENV padrão no Dockerfile. Ao contrário do ARG, você pode passar todos os tipos de variáveis de ambiente para o contêiner. Mesmo aqueles não definidos explicitamente no Dockerfile. Depende do seu aplicativo se isso vai fazer alguma coisa no entanto.
1. Forneça os valores um por um
Na linha de comando, use o sinalizador -e:
$ docker run -e "env_var_name=another_value" alpine env
De um arquivo docker-compose.yml:
version: '3'
services:
plex:
image: linuxserver/plex
environment:
- env_var_name=another_value
2. Passe os valores das variáveis de ambiente do seu host
É o mesmo que o método acima. A única diferença é que você não fornece um valor, mas apenas nomeia a variável. Isso fará com que o Docker acesse o valor atual no ambiente do host e o transmita ao contêiner.
$ docker run -e env_var_name alpine env
Para o arquivo docker-compose.yml, deixe de fora o sinal de equação e tudo depois dele para obter o mesmo efeito.
version: '3'
services:
plex:
image: linuxserver/plex
environment:
- env_var_name
3. Obtenha valores de um arquivo (env_file)
Em vez de escrever as variáveis ou codificá-las (não de bom gosto de acordo com o pessoal de 12 fatores ), podemos especificar um arquivo para ler os valores. O conteúdo de tal arquivo se parece com isto:
env_var_name=another_value
O arquivo acima é chamado env_file_name (nome arbitrário) e está localizado no diretório atual. Você pode fazer referência ao nome do arquivo, que é analisado para extrair as variáveis de ambiente a serem definidas:
$ docker run --env-file=env_file_name alpine env
Com os arquivos docker-compose.yml, apenas referenciamos um env_file e o Docker o analisa para definir as variáveis.
version: '3'
services:
plex:
image: linuxserver/plex
env_file: env_file_name
Aqui está uma pequena folha de dicas, combinando uma visão geral da disponibilidade de ARG e ENV com maneiras comuns de defini-los na linha de comando.

Uma visão geral da disponibilidade de ARG e ENV.
Antes de prosseguirmos: uma pegadinha frequente, se você é novo no Docker e não está acostumado a pensar em imagens e contêineres: se você tentar definir o valor de uma variável de ambiente de dentro de uma instrução RUN como RUN export VARI=5 && ..., não terá acesso a ele em qualquer uma das próximas instruções RUN. A razão para isso é que para cada instrução RUN, um novo contêiner é lançado a partir de uma imagem intermediária. Uma imagem é salva ao final do comando, mas as variáveis de ambiente não persistem dessa forma.
Se você está curioso sobre uma imagem e gostaria de saber se ela fornece valores de variável ENV padrão antes que o contêiner seja iniciado, você pode inspecionar imagens e ver quais entradas ENV são definidas por padrão:
# first, get the images on your system and their ids
$ docker images
# use one of those ids to take a closer look
$ docker inspect image-id
# look out for the "Env" entries
Ufa, isso foi um pouco. A única coisa que resta é - se você tem tantas maneiras diferentes de definir os valores das variáveis ENV, quais substituem as outras?
Substituindo Valores ENV
Supondo que você tenha uma imagem criada a partir de um Dockerfile, que fornece valores ENV padrão. Containers iniciados a partir dele, têm acesso a variáveis ENV definidas no Dockerfile. No entanto, esses valores podem ser substituídos fornecendo variáveis de ambiente únicas, ou env_files , a partir das quais as variáveis de ambiente são analisadas e passadas para o contêiner.
Depois que um processo é executado dentro do contêiner, ou quando um comando é avaliado, eles podem alterar os valores do ambiente por conta própria. Coisas como:
$docker run myimage SOME_VAR=hi python app.py
substituirá completamente qualquer SOME_VAR que você possa ter definido de outra forma para o script app.py, mesmo se houver algum valor com um sinalizador -e antes do comando final.
A precedência é, do mais forte para o menos forte: encher os conjuntos de aplicativos em contêiner, valores de entradas de ambiente único, valores do(s) env_file(s) e, finalmente, padrões do Dockerfile.
Para concluir
Esta foi uma visão realmente completa de todas as maneiras pelas quais você pode definir variáveis ARG e ENV ao criar imagens do Docker e iniciar contêineres. Até agora, você deve ter uma visão geral muito boa de argumentos de tempo de construção, variáveis de ambiente, env_files e modelos de composição docker com arquivos .env. Espero que você tenha obtido muito valor com isso e possa usar o conhecimento para se salvar de muitos bugs no futuro.
Para realmente dominar esses conceitos, apenas ler sobre eles não é suficiente. Você precisa vê-los em ação e aplicá-los ao seu próprio trabalho para realmente torná-los parte de seu cinto de ferramentas. A melhor maneira de garantir que você será capaz de fazer uso dessas informações é aprender fazendo – vá em frente e experimente algumas dessas técnicas em seus projetos atuais!

- o valor que passamos para um argumento tem limite de caracteres
# DOCKERFILE
# arquivo docker
ARG NOMEARG=""
ENV NOMEENV=$NOMEARG
# ${NOMEARG}
docker build --build-arg NOMEARG="TESTE" . -t IMAGE_TAG
- rodar imagem passando environment
docker run -e MG_HOST=$MG_HOST \
-e MG_USER=$MG_USER \
-e MG_PASS=$MG_PASS \
-e MG_AUTH=$MG_AUTH \
-e MG_DB=$MG_DB \
-t image_tag_name_and_version