Respostas:
Você pode passar variáveis de ambiente para seus contêineres com o -e
sinalizador
Um exemplo de um script de inicialização:
sudo docker run -d -t -i -e REDIS_NAMESPACE='staging' \
-e POSTGRES_ENV_POSTGRES_PASSWORD='foo' \
-e POSTGRES_ENV_POSTGRES_USER='bar' \
-e POSTGRES_ENV_DB_NAME='mysite_staging' \
-e POSTGRES_PORT_5432_TCP_ADDR='docker-db-1.hidden.us-east-1.rds.amazonaws.com' \
-e SITE_URL='staging.mysite.com' \
-p 80:80 \
--link redis:redis \
--name container_name dockerhub_id/image_name
Ou, se você não quiser ter o valor na linha de comando em que ele será exibido ps
, etc., -e
poderá extrair o valor do ambiente atual se você o fornecer sem o =
:
sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]
Se você possui muitas variáveis de ambiente e, principalmente, se elas são secretas, pode usar um arquivo env :
$ docker run --env-file ./env.list ubuntu bash
O sinalizador --env-file usa um nome de arquivo como argumento e espera que cada linha esteja no formato VAR = VAL, imitando o argumento passado para --env. As linhas de comentário precisam apenas ser prefixadas com #
export PASSWORD=foo
e a variável será passada docker run
como uma variável de ambiente, fazendo o docker run -e PASSWORD
trabalho.
Você pode passar usando -e
parâmetros com o docker run ..
comando conforme mencionado aqui e como mencionado por @errata.
No entanto, a possível desvantagem dessa abordagem é que suas credenciais serão exibidas na lista de processos, onde você a executa.
Para torná-lo mais seguro, você pode escrever as suas credenciais em um arquivo de configuração e fazer docker run
com --env-file
como mencionado aqui . Em seguida, você pode controlar o acesso desse arquivo de configuração para que outras pessoas que tenham acesso a essa máquina não vejam suas credenciais.
--env-file
, quando você usar --env
seus valores env serão citados / escapados com semântica padrão de qualquer shell que estiver usando, mas ao usar --env-file
os valores que você obterá dentro de seu contêiner será diferente. O comando docker run apenas lê o arquivo, faz uma análise muito básica e passa os valores para o contêiner, não é equivalente à maneira como seu shell se comporta. Apenas um pequeno detalhe para você saber se está convertendo várias --env
entradas para um --env-file
.
Se você estiver usando 'docker-compose' como o método para girar seus contêineres, na verdade, há uma maneira útil de passar uma variável de ambiente definida em seu servidor para o contêiner Docker.
No seu docker-compose.yml
arquivo, digamos que você esteja criando um contêiner hapi-js básico e o código se pareça com:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Digamos que o servidor local em que o seu projeto de docker esteja possui uma variável de ambiente chamada 'NODE_DB_CONNECT' que você deseja passar para o contêiner hapi-js e que o novo nome seja 'HAPI_DB_CONNECT'. Em seguida, no docker-compose.yml
arquivo, você passaria a variável de ambiente local para o contêiner e a renomearia da seguinte maneira:
hapi_server:
container_name: hapi_server
image: node_image
environment:
- HAPI_DB_CONNECT=${NODE_DB_CONNECT}
expose:
- "3000"
Espero que isso ajude você a evitar codificar permanentemente uma string de conexão com o banco de dados em qualquer arquivo do seu contêiner!
Usando docker-compose
, você pode herdar variáveis env no docker-compose.yml e, posteriormente, qualquer Dockerfile (s) chamado (s) por docker-compose
para criar imagens. Isso é útil quando o Dockerfile
RUN
comando deve executar comandos específicos para o ambiente.
(seu shell RAILS_ENV=development
já existe no ambiente)
docker-compose.yml :
version: '3.1'
services:
my-service:
build:
#$RAILS_ENV is referencing the shell environment RAILS_ENV variable
#and passing it to the Dockerfile ARG RAILS_ENV
#the syntax below ensures that the RAILS_ENV arg will default to
#production if empty.
#note that is dockerfile: is not specified it assumes file name: Dockerfile
context: .
args:
- RAILS_ENV=${RAILS_ENV:-production}
environment:
- RAILS_ENV=${RAILS_ENV:-production}
Dockerfile :
FROM ruby:2.3.4
#give ARG RAILS_ENV a default value = production
ARG RAILS_ENV=production
#assign the $RAILS_ENV arg to the RAILS_ENV ENV so that it can be accessed
#by the subsequent RUN call within the container
ENV RAILS_ENV $RAILS_ENV
#the subsequent RUN call accesses the RAILS_ENV ENV variable within the container
RUN if [ "$RAILS_ENV" = "production" ] ; then echo "production env"; else echo "non-production env: $RAILS_ENV"; fi
Dessa forma, não preciso especificar variáveis de ambiente em arquivos ou docker-compose
build
/ up
comandos:
docker-compose build
docker-compose up
Use -e
ou --env value para definir variáveis de ambiente (padrão []).
Um exemplo de um script de inicialização:
docker run -e myhost='localhost' -it busybox sh
Se você deseja usar vários ambientes na linha de comando, antes de cada variável de ambiente, use o -e
sinalizador
Exemplo:
sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh
Nota: Certifique-se de colocar o nome do contêiner após a variável de ambiente, não antes disso.
Se você precisar configurar muitas variáveis, use o --env-file
sinalizador
Por exemplo,
$ docker run --env-file ./my_env ubuntu bash
Para qualquer outra ajuda, consulte a ajuda do Docker:
$ docker run --help
Documentação oficial: https://docs.docker.com/compose/environment-variables/
ubuntu bash
? Aplica-se a imagens criadas com o ubuntu como imagem base ou a todas as imagens?
-e
argumentos atrás! Eu não posso nem começar a entender por que eles fizeram isso necessário ...
Há um truque interessante de como canalizar variáveis de ambiente da máquina host para um contêiner de docker:
env > env_file && docker run --env-file env_file image_name
Use esta técnica com muito cuidado, porque
env > env_file
fará o dump de TODAS as variáveis ENV da máquina hostenv_file
e as tornará acessíveis no contêiner em execução.
Para o Amazon AWS ECS / ECR, você deve gerenciar suas variáveis de ambiente ( especialmente segredos ) por meio de um bucket S3 privado. Consulte a publicação no blog Como gerenciar segredos para aplicativos baseados no Amazon EC2 Container Service usando o Amazon S3 e o Docker .
Se você possui as variáveis de ambiente env.sh
localmente e deseja configurá-las quando o contêiner é iniciado, tente
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && java -jar /<filename>.jar"]
Este comando iniciaria o contêiner com um shell bash (eu quero um shell bash, pois source
é um comando bash), origina o env.sh
arquivo (que define as variáveis de ambiente) e executa o arquivo jar.
Os env.sh
olhares como este,
#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"
Eu adicionei o printenv
comando apenas para testar se o comando de origem real funciona. Você provavelmente deve removê-lo quando confirmar que o comando source funciona bem ou se as variáveis de ambiente apareceriam nos logs do docker.
--env-file
argumento para um docker run
comando. Por exemplo, se você estiver implantando um aplicativo usando o Google app engine e o aplicativo em execução no contêiner precisar de variáveis de ambiente definidas no contêiner de docker, você não terá uma abordagem direta para definir as variáveis de ambiente, pois não tem controle sobre o docker run
comando . Nesse caso, você pode ter um script que descriptografa as variáveis env usando, digamos, KMS e as adiciona às env.sh
quais podem ser originadas para definir as variáveis env.
.
comando POSIX (ponto) disponível em sh
vez regular source
. ( source
é o mesmo que .
) #
Usando jq para converter o env em JSON:
env_as_json=`jq -c -n env`
docker run -e HOST_ENV="$env_as_json" <image>
isso requer jq versão 1.6 ou mais recente
isso coloca o host env como json, essencialmente como no Dockerfile:
ENV HOST_ENV (all env from the host as json)
docker run -e HOST_ENV="$env_as_json" <image>
? : ? No meu caso, o Docker não parece resolver variáveis ou subshells ( ${}
ou $()
) quando passados como argumentos do docker. Por exemplo: A=123 docker run --rm -it -e HE="$A" ubuntu
então dentro desse contêiner: root@947c89c79397:/# echo $HE root@947c89c79397:/#
.... A HE
variável não faz isso.
também podemos hospedar variáveis de ambiente da máquina usando -e flag e $:
docker run -it -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
Usando esse método, defina a variável env automaticamente com o seu nome no meu caso (MG_HOST, MG_USER)
Se você estiver usando python, poderá acessar essas variáveis de ambiente na janela de encaixe,
import os
host,username,password,auth,database=os.environ.get('MG_HOST'),os.environ.get('MG_USER'),os.environ.get('MG_PASS'),os.environ.get('MG_AUTH'),os.environ.get('MG_DB')
docker run --rm -it --env-file <(bash -c 'env | grep <your env data>')
É uma maneira de receber os dados armazenados em um .env
e transmiti-los ao Docker, sem que nada seja armazenado de maneira insegura (para que você não possa apenas olhar docker history
e pegar as chaves.
Digamos que você tenha um monte de coisas da AWS da .env
mesma forma:
AWS_ACCESS_KEY: xxxxxxx
AWS_SECRET: xxxxxx
AWS_REGION: xxxxxx
A execução do docker com o `` docker run --rm -it --env-file <(bash -c 'env | grep AWS_') agarra tudo e passa-o com segurança para ser acessível a partir do contêiner.