Respuestas:
Puede pasar variables de entorno a sus contenedores con la -e
bandera.
Un ejemplo de un script de inicio:
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
O, si no desea tener el valor en la línea de comandos donde se mostrará ps
, etc., -e
puede obtener el valor del entorno actual si solo lo proporciona sin =
:
sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]
Si tiene muchas variables de entorno y especialmente si están destinadas a ser secretas, puede usar un archivo env :
$ docker run --env-file ./env.list ubuntu bash
El indicador --env-file toma un nombre de archivo como argumento y espera que cada línea esté en el formato VAR = VAL, imitando el argumento pasado a --env. Las líneas de comentarios solo necesitan tener el prefijo #
export PASSWORD=foo
lugar y la variable se pasará a docker run
como una variable de entorno, haciendo que docker run -e PASSWORD
funcione.
Puede pasar usando -e
parámetros con el docker run ..
comando como se menciona aquí y como lo menciona @errata.
Sin embargo, la posible desventaja de este enfoque es que sus credenciales se mostrarán en la lista de procesos, donde la ejecuta.
Para hacerlo más seguro, puede escribir sus credenciales en un archivo de configuración y hacer docker run
con --env-file
como se ha mencionado aquí . Luego puede controlar el acceso a ese archivo de configuración para que otras personas que tengan acceso a esa máquina no vean sus credenciales.
--env-file
, cuando use --env
sus valores env, se citarán / escaparán con la semántica estándar de cualquier shell que esté usando, pero cuando use --env-file
los valores que obtendrá dentro de su contenedor serán diferentes. El comando docker run simplemente lee el archivo, realiza un análisis muy básico y pasa los valores al contenedor, no es equivalente al comportamiento de su shell. Solo un pequeño problema para tener en cuenta si está convirtiendo un montón de --env
entradas a un --env-file
.
Si está utilizando 'docker-compose' como método para hacer girar sus contenedores, en realidad hay una forma útil de pasar una variable de entorno definida en su servidor al contenedor Docker.
En su docker-compose.yml
archivo, supongamos que está girando un contenedor básico de hapi-js y el código se ve así:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Supongamos que el servidor local en el que se encuentra su proyecto de Docker tiene una variable de entorno llamada 'NODE_DB_CONNECT' que desea pasar a su contenedor hapi-js y desea que su nuevo nombre sea 'HAPI_DB_CONNECT'. Luego, en el docker-compose.yml
archivo, debe pasar la variable de entorno local al contenedor y cambiarle el nombre de esta manera:
hapi_server:
container_name: hapi_server
image: node_image
environment:
- HAPI_DB_CONNECT=${NODE_DB_CONNECT}
expose:
- "3000"
¡Espero que esto te ayude a evitar codificar una cadena de conexión de base de datos en cualquier archivo de tu contenedor!
Utilizando docker-compose
, puede heredar variables env en docker-compose.yml y, posteriormente, cualquier Dockerfile (s) llamado por docker-compose
construir imágenes. Esto es útil cuando el Dockerfile
RUN
comando debe ejecutar comandos específicos para el entorno.
(su shell RAILS_ENV=development
ya existe en el entorno)
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
De esta manera yo no necesidad de especificar las variables de entorno en archivos o docker-compose
build
/ up
comandos:
docker-compose build
docker-compose up
Use el -e
valor o --env para establecer variables de entorno (predeterminado []).
Un ejemplo de un script de inicio:
docker run -e myhost='localhost' -it busybox sh
Si desea utilizar múltiples entornos desde la línea de comando, antes de cada variable de entorno utilice el -e
indicador.
Ejemplo:
sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh
Nota: Asegúrese de colocar el nombre del contenedor después de la variable de entorno, no antes de eso.
Si necesita configurar muchas variables, use la --env-file
bandera
Por ejemplo,
$ docker run --env-file ./my_env ubuntu bash
Para cualquier otra ayuda, consulte la ayuda de Docker:
$ docker run --help
Documentación oficial: https://docs.docker.com/compose/environment-variables/
ubuntu bash
? ¿Aplica para imágenes creadas con ubuntu como imagen base o para cada imagen?
-e
argumentos de hace años! Ni siquiera puedo empezar a entender por qué hicieron que esto fuera necesario ...
Hay un buen truco para canalizar las variables de entorno de la máquina host a un contenedor acoplable:
env > env_file && docker run --env-file env_file image_name
Use esta técnica con mucho cuidado, porque
env > env_file
volcará TODAS las variables ENV de la máquina hostenv_file
y las hará accesibles en el contenedor en ejecución.
Para Amazon AWS ECS / ECR, debe administrar sus variables de entorno ( especialmente los secretos ) a través de un depósito privado S3. Consulte la publicación del blog Cómo administrar secretos para aplicaciones basadas en Amazon EC2 Container Service mediante Amazon S3 y Docker .
Si tiene las variables de entorno env.sh
localmente y desea configurarlo cuando se inicia el contenedor, puede intentar
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && java -jar /<filename>.jar"]
Este comando iniciaría el contenedor con un shell bash (quiero un shell bash ya que source
es un comando bash), obtiene el env.sh
archivo (que establece las variables de entorno) y ejecuta el archivo jar.
Se env.sh
ve así,
#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"
Agregué el printenv
comando solo para probar que el comando fuente real funciona. Probablemente debería eliminarlo cuando confirme que el comando de origen funciona bien o las variables de entorno aparecerían en los registros de su ventana acoplable.
--env-file
argumento a un docker run
comando. Por ejemplo, si está implementando una aplicación utilizando el motor de aplicaciones de Google y la aplicación que se ejecuta dentro del contenedor necesita variables de entorno establecidas dentro del contenedor de docker, no tiene un enfoque directo para establecer las variables de entorno ya que no tiene control sobre el docker run
comando . En tal caso, podría tener un script que descifre las variables env usando say, KMS, y las agregue a las env.sh
que se pueden obtener para establecer las variables env.
.
comando POSIX (punto) disponible en forma regular en sh
lugar de source
. ( source
es lo mismo que .
)
Usando jq para convertir el env a JSON:
env_as_json=`jq -c -n env`
docker run -e HOST_ENV="$env_as_json" <image>
esto requiere jq versión 1.6 o posterior
esto empuja al host host como json, esencialmente así en Dockerfile:
ENV HOST_ENV (all env from the host as json)
docker run -e HOST_ENV="$env_as_json" <image>
? : En mi caso, Docker no parece resolver variables o subcapas ( ${}
o $()
) cuando se pasa como argumentos de Docker . Por ejemplo: A=123 docker run --rm -it -e HE="$A" ubuntu
luego dentro de ese contenedor: root@947c89c79397:/# echo $HE root@947c89c79397:/#
.... La HE
variable no lo hace.
también podemos hospedar la variable de entorno de la máquina usando -e flag y $:
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
Al usar este método, establezca la variable env automáticamente con su nombre de pila en mi caso (MG_HOST, MG_USER)
Si está utilizando Python, puede acceder a estas variables de entorno dentro de Docker al
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>')
Es una forma de recopilar los datos almacenados dentro de a .env
y pasarlos a Docker, sin que nada se almacene de forma insegura (por lo que no puede simplemente mirar docker history
y tomar las teclas.
Digamos que tiene un montón de cosas de AWS en su .env
gusto, así:
AWS_ACCESS_KEY: xxxxxxx
AWS_SECRET: xxxxxx
AWS_REGION: xxxxxx
ejecutando docker con `` docker run --rm -it --env-file <(bash -c 'env | grep AWS_') lo tomará todo y lo pasará de forma segura para que sea accesible desde dentro del contenedor.