run - Cómo usar variables de entorno en Docker compose
docker tag (11)
Me gustaría poder usar variables env dentro de docker-compose.yml, con valores pasados en el momento de docker-compose. Este es el ejemplo. Estoy haciendo esto hoy con el comando básico Docker Run, que está envuelto alrededor de mi propio script. ¿Hay alguna manera de lograrlo con componer, sin esos envoltorios de bash?
proxy:
hostname: $hostname
volumes:
- /mnt/data/logs/$hostname:/logs
- /mnt/data/$hostname:/data
La solución DOCKER:
Parece que docker-compose 1.5+ ha habilitado la sustitución de variables: https://github.com/docker/compose/releases
El último Docker Compose le permite acceder a variables de entorno desde su archivo de redacción. Para que pueda obtener sus variables de entorno, luego ejecute Compose así:
set -a
source .my-env
docker-compose up -d
Luego puede hacer referencia a las variables en docker-compose.yml usando $ {VARIABLE}, así:
db:
image: "postgres:${POSTGRES_VERSION}"
Y aquí hay más información de los documentos, tomada aquí: docs.docker.com/compose/compose-file/#variable-substitution
Cuando ejecuta docker-compose con esta configuración, Compose busca la variable de entorno POSTGRES_VERSION en el shell y sustituye su valor en. Para este ejemplo, Compose resuelve la imagen en postgres: 9.3 antes de ejecutar la configuración.
Si no se establece una variable de entorno, Componer sustituye con una cadena vacía. En el ejemplo anterior, si POSTGRES_VERSION no está configurado, el valor de la opción de imagen es postgres :.
Se admiten las sintaxis $ VARIABLE y $ {VARIABLE}. Las características extendidas de estilo de shell, como $ {VARIABLE-default} y $ {VARIABLE / foo / bar}, no son compatibles.
Si necesita poner un signo de dólar literal en un valor de configuración, use un signo de dólar doble ($$).
Y creo que esta característica se agregó en esta solicitud de extracción: https://github.com/docker/compose/pull/1765
La solución BASH:
Noté que la gente tiene problemas con el soporte de variables de entorno de Docker.
En lugar de tratar con variables de entorno en Docker, volvamos a lo básico, como bash!
Aquí hay un método más flexible que utiliza un script bash y un archivo
.env
.
Un ejemplo de archivo .env:
EXAMPLE_URL=http://example.com
# Note that the variable below is commented out and will not be used:
# EXAMPLE_URL=http://example2.com
SECRET_KEY=ABDFWEDFSADFWWEFSFSDFM
# You can even define the compose file in an env variable like so:
COMPOSE_CONFIG=my-compose-file.yml
# You can define other compose files, and just comment them out
# when not needed:
# COMPOSE_CONFIG=another-compose-file.yml
luego ejecute este script bash en el mismo directorio, que debería implementar todo correctamente:
#!/bin/bash
docker rm -f `docker ps -aq -f name=myproject_*`
set -a
source .env
cat ${COMPOSE_CONFIG} | envsubst | docker-compose -f - -p "myproject" up -d
Simplemente haga referencia a sus variables env en su archivo de
${SECRET_KEY}
con la sintaxis bash habitual (es decir,
${SECRET_KEY}
para insertar
SECRET_KEY
del archivo
.env
).
Tenga en cuenta que
COMPOSE_CONFIG
se define en mi archivo
.env
y se usa en mi script bash, pero puede reemplazar fácilmente
{$COMPOSE_CONFIG}
con
my-compose-file.yml
en el script bash.
También tenga en cuenta que etiqueté esta implementación al nombrar todos mis contenedores con el prefijo "myproject". Puede usar cualquier nombre que desee, pero ayuda a identificar sus contenedores para que pueda consultarlos fácilmente más adelante. Suponiendo que sus contenedores no tienen estado, como deberían ser, este script eliminará y volverá a implementar sus contenedores rápidamente de acuerdo con sus parámetros de archivo .env y su archivo YAML de composición.
Actualización Dado que esta respuesta parece bastante popular, escribí una publicación de blog que describe mi flujo de trabajo de implementación de Docker con más profundidad: http://lukeswart.net/2016/03/lets-deploy-part-1/ Esto podría ser útil cuando agregue más complejidad para una configuración de implementación, como configuraciones nginx, certificados LetsEncrypt y contenedores vinculados.
agregar env al archivo .env
Como
VERSION=1.0.0
luego guárdelo para
deploy.sh
INPUTFILE=docker-compose.yml
RESULT_NAME=docker-compose.product.yml
NAME=test
prepare() {
local inFile=$(pwd)/$INPUTFILE
local outFile=$(pwd)/$RESULT_NAME
cp $inFile $outFile
while read -r line; do
OLD_IFS="$IFS"
IFS="="
pair=($line)
IFS="$OLD_IFS"
sed -i -e "s//${${pair[0]}}/${pair[1]}/g" $outFile
done <.env
}
deploy() {
docker stack deploy -c $outFile $NAME
}
prepare
deploy
-
Cree un
template.yml
, que es sudocker-compose.yml
con variable de entorno. - Suponga que sus variables de entorno están en un archivo ''env.sh''
- Coloque el siguiente código en un archivo sh y ejecútelo.
fuente env.sh; rm -rf docker-compose.yml; envsubst <"template.yml"> "docker-compose.yml";
Se
docker-compose.yml
un nuevo archivo
docker-compose.yml
con los valores correctos de las variables de entorno.
Ejemplo de archivo template.yml:
oracledb:
image: ${ORACLE_DB_IMAGE}
privileged: true
cpuset: "0"
ports:
- "${ORACLE_DB_PORT}:${ORACLE_DB_PORT}"
command: /bin/sh -c "chmod 777 /tmp/start; /tmp/start"
container_name: ${ORACLE_DB_CONTAINER_NAME}
Archivo env.sh de muestra:
#!/bin/bash
export ORACLE_DB_IMAGE=<image-name>
export ORACLE_DB_PORT=<port to be exposed>
export ORACLE_DB_CONTAINER_NAME=ORACLE_DB_SERVER
Cuando use variables de entorno para volúmenes que necesita:
-
cree el archivo .env en la misma carpeta que contiene el archivo
docker-compose.yaml
-
declarar variable en el archivo
.env
:HOSTNAME=your_hostname
-
Cambie
$hostname
a${HOSTNAME}
en el archivodocker-compose.yaml
proxy: hostname: ${HOSTNAME} volumes: - /mnt/data/logs/${HOSTNAME}:/logs - /mnt/data/${HOSTNAME}:/data
Por supuesto, puede hacerlo dinámicamente en cada compilación como:
echo "HOSTNAME=your_hostname" > .env && sudo docker-compose up
La mejor manera es especificar variables de entorno fuera del archivo
docker-compose.yml
.
Puede usar la configuración
env_file
y definir su archivo de entorno dentro de la misma línea.
Luego, hacer una compilación de docker nuevamente debería recrear los contenedores con las nuevas variables de entorno.
Así es como se ve mi docker-compose.yml:
web:
environment:
- DEBUG=1
POSTGRES_PASSWORD: ''postgres''
POSTGRES_USER: ''postgres''
Nota: docker-compose espera que cada línea en un archivo env esté en formato
VAR=VAL
. Evite utilizar laexport
dentro del archivo.env
. Además, el archivo.env
debe colocarse en la carpeta donde se ejecuta el comando docker-compose.
Lo siguiente es aplicable para docker-compose 3.x Establecer variables de entorno dentro del contenedor
método - 1 método recto
$ cat .env
TAG=v1.5
POSTGRES_PASSWORD: ''postgres''
método - 2 El archivo ".env"
Cree un archivo .env en la misma ubicación que docker-compose.yml
$ cat docker-compose.yml
version: ''3''
services:
web:
image: "webapp:${TAG}"
postgres_password: "${POSTGRES_PASSWORD}"
y tu archivo de redacción será como
services:
web:
env_file: variables.env
No puedes ... todavía. Pero esta es una alternativa, piense como un generador docker-composer.yml:
https://gist.github.com/Vad1mo/9ab63f28239515d4dafd
Básicamente un script de shell que reemplazará sus variables. También puede usar la tarea Grunt para construir su archivo de composición de Docker al final de su proceso de CI.
Parece que docker-compose tiene soporte nativo ahora para las variables de entorno predeterminadas en el archivo .
todo lo que necesita hacer es declarar sus variables en un archivo llamado
.env
y estarán disponibles en docker-compose.yml.
Por ejemplo, para el archivo
.env
con contenido:
MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image
Puede acceder a su variable dentro de
docker-compose.yml
o reenviarlos al contenedor:
my-service:
image: ${IMAGE_NAME}
environment:
MY_SECRET_KEY: ${MY_SECRET_KEY}
Tengo un script bash simple que creé para esto, solo significa ejecutarlo en su archivo antes de usarlo: https://github.com/antonosmond/subber
Básicamente, simplemente cree su archivo de composición utilizando llaves dobles para denotar variables de entorno, por ejemplo:
app:
build: "{{APP_PATH}}"
ports:
- "{{APP_PORT_MAP}}"
Cualquier cosa entre llaves dobles se reemplazará con la variable de entorno del mismo nombre, así que si tuviera las siguientes variables de entorno establecidas:
APP_PATH=~/my_app/build
APP_PORT_MAP=5000:5000
al ejecutar
subber docker-compose.yml
el archivo resultante se vería así:
app:
build: "~/my_app/build"
ports:
- "5000:5000"
Utilice el archivo .env para definir valores dinámicos en docker-compse.yml. Ya sea puerto o cualquier otro valor.
Muestra docker-compose:
testcore.web:
image: xxxxxxxxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/testcore:latest
volumes:
- c:/logs:c:/logs
ports:
- ${TEST_CORE_PORT}:80
environment:
- CONSUL_URL=http://${CONSUL_IP}:8500
- HOST=${HOST_ADDRESS}:${TEST_CORE_PORT}
Dentro del archivo .env puede definir el valor de estas variables:
CONSUL_IP=172.31.28.151
HOST_ADDRESS=172.31.16.221
TEST_CORE_PORT=10002