Compose: Variáveis ​​de ambiente não são aplicadas na construção de contêiner

Criado em 10 ago. 2015  ·  16Comentários  ·  Fonte: docker/compose

Ao construir o contêiner, as variáveis ​​de ambiente não são aplicadas.

docker-compose.yml:

img:
    build: img
    environment:
        VAR: Hello

/ img / Dockerfile:

FROM python:2.7
RUN python -c 'import os; print os.environ["VAR"]'

Esperava-se que "Hello" tivesse sido escrito e recebido KeyError: VAR - variável de ambiente ausente.

Se você entrar no container com docker-compose run --rm img bash (depois de remover a última linha com falha) e fizer python -c 'import os; print os.environ["VAR"]' você obterá o resultado esperado.

docker-compose==1.3.3

docker-version :

Client version: 1.7.1
Client API version: 1.19
Go version (client): go1.4.2
Git commit (client): 786b29d
OS/Arch (client): linux/amd64
Server version: 1.7.1
Server API version: 1.19
Go version (server): go1.4.2
Git commit (server): 786b29d
OS/Arch (server): linux/amd64
kinquestion

Comentários muito úteis

a resposta a esta questão de estouro de pilha ajudou https://stackoverflow.com/questions/19537645/get-environment-variable-value-in-dockerfile

é possível mapear as variáveis ​​de ambiente .env para ARGS a serem usadas pelo Dockerfile durante a construção.

docker-compose.yml

version: "2"
services:

  lumen:
    build:
      context: .
      dockerfile: ./Dockerfile
      args:
        - PORT=${PORT}
    volumes:
       ...

Dockerfile

FROM php:7.0-apache
ARG PORT

ENV PORT "$PORT"

EXPOSE ${PORT}
...

Todos 16 comentários

Isso é esperado. A chave environment: em docker-compose.yml é o mesmo que especificá-la para o comando docker run para iniciar o contêiner. build e dockerfile são as chaves antigas usadas para construir a imagem.

Isso talvez não seja óbvio na documentação e pode ser melhorado.

O Docker não oferece suporte para injeção de ambiente no ambiente de construção (deve ser parte do Dockerfile), mas acredito que existem algumas propostas abertas para adicionar suporte para algo assim.

Apenas uma referência para quem encontrar esse problema, aqui está a discussão docker sobre variáveis ​​de tempo de compilação: https://github.com/docker/docker/issues/14634 e PR correspondente: https://github.com/docker/docker / pull / 15182

Isso é difícil, realmente precisa de melhores documentos.

A documentação é realmente confusa, por exemplo, fala sobre env-file, que é usado para docker-compose.yml e é usado para docker run . Dado que docker-compose é uma ferramenta de orquestração para construir e executar contêineres, é fácil supor que o ambiente se aplicaria ao tempo de construção, usando --env <key>=<value> ou algo assim.

Me mordeu também.
Apenas para deixar uma nota que as variáveis ​​de ambiente podem ser definidas como argumentos de construção no arquivo de composição. Como outros neste tópico, inicialmente esperava que env_file ou ambiente fosse usado tanto para compilar quanto para executar.
Verificado com compose file v2, docker-compose v1.7, docker-engine v1.11.

Observe que, se precisar incluir env vars de um arquivo, você pode fazer o seguinte. Isso exigirá (na seção de compilação docker-compose) args definidos a partir dessas variáveis, que você pode consultar no arquivo docker. Isso significa que, embora você não possa reutilizar diretamente o env_file, pode fazer isso com um pouco de trabalho extra.

env $(cat vars.env | xargs) docker-compose up --build <whatever>

a resposta a esta questão de estouro de pilha ajudou https://stackoverflow.com/questions/19537645/get-environment-variable-value-in-dockerfile

é possível mapear as variáveis ​​de ambiente .env para ARGS a serem usadas pelo Dockerfile durante a construção.

docker-compose.yml

version: "2"
services:

  lumen:
    build:
      context: .
      dockerfile: ./Dockerfile
      args:
        - PORT=${PORT}
    volumes:
       ...

Dockerfile

FROM php:7.0-apache
ARG PORT

ENV PORT "$PORT"

EXPOSE ${PORT}
...

@williamli Você pode adicionar um link para a pergunta Stack Overflow?

Desculpe pessoal - não tenho certeza se entendi como resolver isso - e gostaria de usar uma imagem pré-construída.

Por exemplo, meu arquivo de composição é:

versão: '3'

Serviços:
web1:
imagem: softwaremaker / web-w
meio Ambiente:

  • wtmsdemo_customerapi01 = http: // api1 / api / values
    portas:
  • "89:80"
    depende de:
  • api1
    api:
    imagem: softwaremaker / api-w
    redes:
    padrão:
    externo:

nome: nat

Eu costumava pensar que a imagem api (softwaremaker / api-w) seria capaz de resolver nas variáveis ​​de ambiente que eu havia configurado acima, mas não funciona.

@PatrLind
adicionado o link stackoverflow ao meu comentário original.

https://stackoverflow.com/questions/19537645/get-environment-variable-value-in-dockerfile

O problema ainda é relevante para arquivos env diferentes do arquivo .env padrão.
O código Fe Next não funcionará:

  nginx:
    env_file:
      - .env
      - .env.local
    environment:
     - SERVER_NAME=${SERVER_NAME}
    build:
      context: ./nginx
      dockerfile: Dockerfile
      args:
        server_name: ${SERVER_NAME}

enquanto SERVER_NAME é definido no segundo arquivo env ( .env.local ).
Não vejo opções para passar env vars de .env.local para o contexto de construção ((

@remort
Eu posso confirmar isso também, se eu tiver variáveis ​​sendo usadas durante a compilação, elas só serão passadas para o processo de compilação se o arquivo for chamado de .env se elas forem chamadas de .env.docker eles não recebem pegou. Mesmo quando o env_file é especificado para usar o arquivo .env.docker .

Minha solução para isso durante meu build copiando o outro arquivo env nomeado e renomeando-o para .env

COPY .env.docker ${APP_HOME}/.env
WORKDIR $APP_HOME

Depois disso, pareceu pegar as variáveis ​​de ambiente quando o contêiner é executado

Sistema operacional: macOS (10.14.6)
Versão do Docker Desktop: 2.1.0.5 (40693)
Versão do motor: 19.03.5
Compor: 1.24.1

Oi pessoal,

Uma pergunta rápida para todos vocês: essa é a melhor maneira de construir uma imagem para o desenvolvedor? Funciona bem até agora. No entanto, essa é a prática recomendada? Todas as imagens são baseadas em buster.

`` `
FROM redis: buster as redis
RUN mkdir / env && env> /env/.env_redis
RUN cat / etc / passwd
RUN ls -lah / home
DE Ruby: Slim Buster AS Ruby
RUN mkdir / env && env> /env/.env_ruby

Nó FROM: nodo AS lts-buster-slim
RUN mkdir / env && env> /env/.env_node

construir nginx

DE nginx: AS nginx mais recente
RUN mkdir / env && env> /env/.env_nginx

construir php

DE php: fpm-buster AS php

DE php: 7.3.14-fpm-buster AS php

RUN mkdir / env && env> /env/.env_php
COPY --from = redis / /
COPY --from = ruby ​​/ /
COPY --from = node / /
COPY --from = nginx / /

ADICIONE conf / include-site.conf /etc/nginx/conf.d/include-site.conf
ADICIONE conf / supervisord.conf /etc/supervisord.conf

RUN su root
EXPOR 80 443
WORKDIR "/ var / www / html"

ENTRYPOINT ["/ bin / bash", "/start.sh"]

O problema ainda existe.
A chave env_file na seção de construção será mais clara do que passar env vars por meio de args para a construção de contêiner.
Como isso:

#NOT_WORKING
build:
      context: ./client
      dockerfile: Dockerfile
      env_file: ${CURRENT_ENV_FILE}

Porque estou usando scripts de shell para construir e compor docker.
Para produção, preciso de env_file diferente do dev / local.
E há muitos arquivos docker-compose.env.yml com muitos argumentos, então não é conveniente como eu penso

Acho que deve haver uma maneira elegante de contornar isso. Eu realmente gosto da sintaxe do docker e usar argumentos em vez de variáveis ​​de ambiente não faz sentido para mim. Eu não gostaria que alguém alterasse manualmente meus arquivos docker-compose. Alterar valores nos arquivos .env parece consistente para mim.

Esta página foi útil?
0 / 5 - 0 avaliações