Respostas:
Você pode passar variáveis de ambiente para seus contêineres com o -esinalizador
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., -epoderá 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=fooe a variável será passada docker runcomo uma variável de ambiente, fazendo o docker run -e PASSWORDtrabalho.
Você pode passar usando -eparâ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 runcom --env-filecomo 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 --envseus valores env serão citados / escapados com semântica padrão de qualquer shell que estiver usando, mas ao usar --env-fileos 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 --enventradas 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.ymlarquivo, 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.ymlarquivo, 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-composepara criar imagens. Isso é útil quando o Dockerfile RUNcomando deve executar comandos específicos para o ambiente.
(seu shell RAILS_ENV=developmentjá 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/ upcomandos:
docker-compose build
docker-compose up
Use -eou --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 -esinalizador
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-filesinalizador
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?
-eargumentos 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_filefará o dump de TODAS as variáveis ENV da máquina hostenv_filee 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.shlocalmente 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.sharquivo (que define as variáveis de ambiente) e executa o arquivo jar.
Os env.sholhares como este,
#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"
Eu adicionei o printenvcomando 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-fileargumento para um docker runcomando. 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 runcomando . Nesse caso, você pode ter um script que descriptografa as variáveis env usando, digamos, KMS e as adiciona às env.shquais podem ser originadas para definir as variáveis env.
.comando POSIX (ponto) disponível em shvez 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" ubuntuentão dentro desse contêiner: root@947c89c79397:/# echo $HE root@947c89c79397:/# .... A HEvariá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 .enve transmiti-los ao Docker, sem que nada seja armazenado de maneira insegura (para que você não possa apenas olhar docker historye pegar as chaves.
Digamos que você tenha um monte de coisas da AWS da .envmesma 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.