Moby: `docker stack deployment` en 1.13 no carga el archivo `.env` como lo hace `docker-compose up`

Creado en 5 dic. 2016  ·  93Comentarios  ·  Fuente: moby/moby

Para probar la función docker stack deploy --compose-file , cargo uno de mis docker-compose.yml de muestra:

version: '3'
services:
    nginx:
        image: "${DOCKER_USER}/lnmp-nginx:v1.2"
        build:
            context: .
            dockerfile: Dockerfile.nginx
        ports:
            - "80:80"
        networks:
            - frontend
        depends_on:
            - php
    php:
        image: "${DOCKER_USER}/lnmp-php:v1.2"
        build:
            context: .
            dockerfile: Dockerfile.php
        networks:
            - frontend
            - backend
        environment:
            MYSQL_PASSWORD: Passw0rd
        depends_on:
            - mysql
    mysql:
        image: mysql:5.7
        volumes:
            - mysql-data:/var/lib/mysql
        environment:
            TZ: 'Asia/Shanghai'
            MYSQL_ROOT_PASSWORD: Passw0rd
        command: ['mysqld', '--character-set-server=utf8']
        networks:
            - backend
volumes:
    mysql-data:

networks:
    frontend:
    backend:

En la sección image del servicio nginx y php , usé ${DOCKER_USER} para obtener la identificación de la ventana acoplable de las variables de entorno. Y si uso docker-compose up , cargará el archivo .env como archivos envvar predeterminados, cuyo contenido es:

DOCKER_USER=twang2218

Sin embargo, si uso docker stack para implementar este docker-compose.yml , obtendré los siguientes errores:

$ docker stack deploy --compose-file docker-compose.yml lnmp
Ignoring unsupported options: build

Creating network lnmp_frontend
Creating network lnmp_backend
Creating network lnmp_default
Creating service lnmp_php
Error response from daemon: rpc error: code = 3 desc = ContainerSpec: "/lnmp-php:v1.2" is not a valid repository/tag

Como puede ver, como el comando docker stack deploy no cargó el archivo .env , el ${DOCKER_USER} fue reemplazado por una cadena vacía, lo que hace que el nombre de la imagen no sea válido.

Si se cargó el archivo .env , el nombre de la imagen final debería ser twang2218/lnmp-php:v1.2 .

La sustitución del entorno realmente funciona, si ejecuto el comando de esta manera:

$ DOCKER_USER=twang2218 docker stack deploy --compose-file docker-compose.yml lnmp
Ignoring unsupported options: build

Creating network lnmp_frontend
Creating network lnmp_backend
Creating network lnmp_default
Creating service lnmp_mysql
Creating service lnmp_nginx
Creating service lnmp_php

Y podemos verificar que funciona con el comando docker service inspect :

$ docker service inspect lnmp_php | grep Image
                    "Image": "twang2218/lnmp-php:v1.2<strong i="13">@sha256</strong>:4f1aef1350aeef3f757f6b6da8f2e1a79ff849f61382320e4b668bfe2b0d1c5a",

El nombre de la imagen es twang2218/lnmp-php:v1.2 , lo cual es correcto.

Probé esta función en la gota Digtial Ocean, que instaló la ventana acoplable 1.13.0-rc2 a través docker-machine .

Aquí está la versión:

$ docker version
Client:
 Version:      1.13.0-rc2
 API version:  1.25
 Go version:   go1.7.3
 Git commit:   1f9b3ef
 Built:        Wed Nov 23 06:32:39 2016
 OS/Arch:      linux/amd64

Server:
 Version:             1.13.0-rc2
 API version:         1.25
 Minimum API version: 1.12
 Go version:          go1.7.3
 Git commit:          1f9b3ef
 Built:               Wed Nov 23 06:32:39 2016
 OS/Arch:             linux/amd64
 Experimental:        false

Aquí está el docker info :

root<strong i="25">@d1</strong>:~/docker-lnmp# docker info
Containers: 7
 Running: 1
 Paused: 0
 Stopped: 6
Images: 4
Server Version: 1.13.0-rc2
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 43
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
Swarm: active
 NodeID: vyf3mgcj3uonrnh5xxquasp38
 Is Manager: true
 ClusterID: jb8rxvd6ptrn3psfkiixxed7r
 Managers: 1
 Nodes: 3
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot Interval: 10000
  Number of Old Snapshots to Retain: 0
  Heartbeat Tick: 1
  Election Tick: 3
 Dispatcher:
  Heartbeat Period: 5 seconds
 CA Configuration:
  Expiry Duration: 3 months
 Node Address: 138.197.195.206
 Manager Addresses:
  138.197.195.206:2377
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 03e5862ec0d8d3b3f750e19fca3ee367e13c090e
runc version: 51371867a01c467f08af739783b8beafc154c4d7
init version: 949e6fa
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.4.0-51-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 488.5 MiB
Name: d1
ID: E6UB:PHX6:I2KY:Q35T:PCCI:MFDQ:ZMMN:2X7K:DEOZ:PAP7:4BUC:FP6X
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Labels:
 provider=digitalocean
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false
arestack areswarm kinenhancement

Comentario más útil

@whoan Estoy usando esto como una solución alternativa:

env $(cat .env | grep ^[A-Z] | xargs) docker stack deploy --compose-file docker-compose.yml [STACK_NAME]

De esa forma, las variables no se atascan en la ventana de la terminal.

Todos 93 comentarios

Esto es por diseño. La compatibilidad con .env es una característica de Compose, no del formato de archivo.

Podemos discutir agregar esto para una versión futura, pero no sé si realmente es la mejor opción.

El soporte .env es muy útil en Compose, lo usamos en muchos de nuestros archivos de composición. Separa las partes dinámicas y las partes estáticas del archivo docker-compose.yml . Con la carga .env de forma predeterminada, podemos simplemente proporcionar un archivo .env diferente para diferentes entornos y mantener los scripts docker-compose.yml y relacionados estáticos.

No es posible usar env_file o environment en docker-compose.yml para lograr el mismo resultado de sustitución de envvars. .env es la forma más fácil de hacerlo.

De lo contrario, tenemos que prefijar export en cada línea del archivo .env y manualmente source .env cada vez antes de cargar el docker-compose.yml , y los pasos adicionales a veces son propensos equivocarse.

Acabo de notar esto.
Asumí/esperaba que funcionara de la misma manera que para Compose, pero no es el caso para docker deploy .

En mi caso particular, esperaba usar el archivo .env para almacenar datos confidenciales (contraseñas, claves API, etc.) utilizados en los servicios que crearé en la pila:

version: '3'

volumes:
  data:
    driver: local

networks:
  backend:
    driver: overlay

services:
  rabbitmq:
    image: rabbitmq:${EXCHANGE_RABBITMQ_TAG}
    volumes: [ "data:/var/lib/rabbitmq" ]
    logging: { driver: gelf, options: { gelf-address: "udp://0.0.0.0:12201" } }
    networks: [ "backend" ]
    ports: [ "15672:15672", "5672:5672" ]
    environment:
      RABBITMQ_DEFAULT_USER: ${EXCHANGE_RABBITMQ_USER}
      RABBITMQ_DEFAULT_PASS: ${EXCHANGE_RABBITMQ_PASS}
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          - node.labels.queue-host == true

Si bien este archivo Compose se registrará en Git, el archivo .env se ignorará.

He seguido todo el material/historial de los archivos *.dab vs compose, y siento que ustedes están tratando de evitar algo, o proponiendo una mejor solución, pero perdí el hilo de toda la discusión...

Hola a todos,

Versión acoplable: v1.13.0-rc4

Recibo el error: Ignorar opciones no admitidas: compilación . ¿Significa que no creará una compilación desde Dockerfile?

Y también obtengo el mismo error para network_mode: Ignoring unsupported options: network_mode.

A continuación se muestra el comando:
DOCKER_IMAGE=akhil123 docker stack deployment -c docker-compose.yml foo

Muchas gracias de antemano.

@akhildangore , por favor, no comente sobre problemas con preguntas que no estén directamente relacionadas. La función docker stack deploy , _por diseño_ no realiza compilaciones. La razón de esto es que se realiza una _construcción_ en el host desde el que se ejecuta el comando, por lo que la imagen solo estará disponible en _ese_ nodo. Al implementar esa imagen en un Swarm, el servicio no se puede iniciar en otros nodos. Para implementar servicios, asegúrese de que la imagen que está implementando se inserte en un registro (o para realizar pruebas, asegúrese de que la imagen esté disponible en todos los nodos del enjambre)

¿Hay algún caso/discusión a favor o en contra de apoyar este comportamiento en docker deploy ?

@vovimayhem aún no se ha tomado una decisión sobre el archivo .env , pero es posible que le interese https://github.com/docker/docker/pull/30144 , que agrega soporte para secretos al archivo de redacción

Acabo de encontrar esa discusión. ¡Excelente!

Estoy usando una función bash como solución alternativa.

Puede adaptarlo a sus necesidades hasta que se lance la función secrets :

dsd() {
    stack=${1:-${PWD##*/}} # by default, the name of the cointaining folder
    compose_file=${2:-docker-compose.yml}

    if [ ! -f $compose_file ]; then
        echo "Misses compose file: $compose_file" >&2
        return 1
    fi

    # execute as a subcommand in order to avoid the variables remain set
    (
        # export variables excluding comments
        [ -f .env ] && export $(sed '/^#/d' .env)

        # Use dsd your_stack your_compose_file to override the defaults
        docker stack deploy --compose-file $compose_file $stack
    )
}

Para aquellos que se suscriban a este número; El soporte de secretos para los archivos docker-compose se incluirá en la versión 1.13.1, que no debería ser muy lejana en el futuro.

@whoan Estoy usando esto como una solución alternativa:

env $(cat .env | grep ^[A-Z] | xargs) docker stack deploy --compose-file docker-compose.yml [STACK_NAME]

De esa forma, las variables no se atascan en la ventana de la terminal.

Siempre es bueno tener la capacidad de cargar cosas desde un archivo .env ; además de un caso de uso de secretos de Docker más simple que ahora se puede eludir, siempre hay valores de Docker Compose que no desea tener codificados. en tu repositorio.

Supongamos que usa docker stack deploy para implementar una pila completa y tiene los siguientes requisitos:

  • desea utilizar exactamente la misma configuración para diferentes entornos, por ejemplo, puesta en escena y producción

    • necesita tener diferentes valores de escala para cada entorno

Si no puede configurar esto con un archivo .env , debe cambiar manualmente el archivo docker-compose.yml antes de implementar la pila cada vez; de lo contrario, el valor de escala del servicio volverá a 1.

Puede ampliar lo anterior con cosas como redes, configurar el DNS que debe escuchar un servicio, etc.

Puedo redactar un PR que cargue un archivo .env , si existe uno en el mismo directorio que docker-compose.yml si creemos que los casos de uso anteriores tienen sentido.

El diseño de docker stack deployment es un poco diferente de los comandos docker-compose . No creo que tenga sentido simplemente leer un .env por defecto. Ni siquiera docker-compse.yml se lee de forma predeterminada, porque en el futuro la fuente de implementación predeterminada probablemente será otra.

Siempre puede obtener un archivo .env usted mismo antes de ejecutar stack deploy .

Solo . .env antes de llamar a docker stack deploy no ayuda, las $variables no se sustituyen. Solo el truco env .. xargs ayudó.
Sería bueno tener la opción --env-file=FILE como en docker run .

Sólo . .env antes de llamar a docker stack deployment no ayuda

Esto debería ayudar a @C-Pro: debe tener export ... líneas en su archivo .env . Alternativamente, puede hacer export $(cat .env) , lo que funcionaría para la mayoría de los casos.

Hola a todos,
Hoy traté de ejecutar docker stack deploy .
Mi archivo docker-compose.yml :

version: '3'
services:
  simple:
    image: alpine
    environment:
      - FOO: ${BAR}
    env_file: .env

Y .env archivo en el mismo directorio:

BAR=worked

Después del lanzamiento docker stack deploy -c docker-compose.yml test , inspeccioné el contenedor y obtuve esto:

$ env
BAR=worked
FOO=
...

Parece que .env se proporcionan en el contenedor, pero no se proporcionan en la máquina host.
Significa que puedo usar el archivo .env en lugar de la sección environment , pero no puedo usar el archivo .env con sustitución de variable.
Versión acoplable: v17.03

@ddpaimon
ambiente:
- COMIDA=${BAR}

Parece que el archivo .env solo funciona para el contenedor, pero no para el reemplazo de la variable del archivo docker-compose.yml.

Docker para MAC, Docker versión 17.03.1-ce, compilación c6d412e

@realcbb
Si. Pero para usar variables de archivo .env dentro del contenedor, debe eliminarlas en la sección environment .
Por ejemplo:
docker-compose.yml

...
environment:
  - FOO=${FOO:-empty}
...

.env

FOO=filled

En el contenedor tengo esto:

$ env
FOO=empty

Pero si elimino FOO de la sección environment en docker-compose.yml , obtengo esto:

$ env
FOO=filled

@ddpaimon
Las variables de entorno especificadas en el entorno anulan estos valores especificados en el archivo .env.

@dnephin : afirma que .env no es parte del formato de archivo de composición de la ventana acoplable. Sin embargo, la característica del archivo .env está documentada en la referencia de la versión 3 del archivo Compose: https://docs.docker.com/compose/compose-file/#variable -substitution .
Esto da la impresión de que .env también debería funcionar con la implementación de la pila acoplable.
Además de eso, como ya lo mencionaron otros, separar los valores específicos del entorno real de la definición de pila yaml es una característica muy deseada/necesaria. Específicamente, queremos usarlo para especificar versiones y replicaciones de imágenes.

Gracias, abrí https://github.com/docker/docker.github.io/issues/3654 para arreglar los documentos

docker stack deploy puede tomar un archivo generado. Esto funciona en bash para todas mis variables y también mantiene los secretos en secreto:

docker stack deploy --with-registry-auth --compose-file=<(ENV1=value1 ENV2=value2 docker-compose -f docker-compose.yaml -f docker-compose.override.yaml -f third-sample-compose.yaml config) stack-name

Tenga en cuenta que agregué las variables ENV en línea como adicionales o anulaciones. Mis archivos de composición hacen referencia a archivos .env y esto funciona. Espero que esto sea útil 👍

La funcionalidad de docker-compose config es lo que une esto.

Encontré este problema cuando buscaba una solución para que mi .env no fuera leído por docker stack deploy . Me sorprendió un poco ver que no era compatible (los documentos podrían aclararse), pero quiero agregar mi soporte para .env , como componer.

Mi caso de uso es que uso docker stack deploy en entornos de desarrollo, prueba y preparación y uso variables de entorno para las opciones de pila para mantener el archivo yml igual.

Actualmente, se usa una de las soluciones alternativas publicadas aquí, pero la ruta preferida sería usar un archivo .env .

Solo un recordatorio amistoso: puede existir la posibilidad de que esté tratando de usar archivos dotenv para almacenar claves de API, contraseñas y otras cosas consideradas "sensibles" para colocarlas en el clúster. Para estos casos, debe utilizar Docker Secrets .

Para otras cosas, ¿puedo sugerir tener un archivo de redacción por entorno implementado/desplegable? La mayoría de las cosas que cambian entre diferentes entornos serán los servidores disponibles, la organización de servidores diferentes, etc... y, por lo tanto, necesitarán valores diferentes en los contenidos deploy placement , resources reservas, etc.), lo que hace que usar un solo archivo para todo sea demasiado complicado.

En realidad, quiero esta característica, las variables en el archivo de redacción se pueden tratar como un valor diferente en un host diferente cuando se usa la implementación de la pila acoplable.

"Para otras cosas, ¿puedo sugerir tener un archivo de composición por entorno implementado/implementable? La mayoría de las cosas que cambian entre diferentes entornos serán los servidores disponibles, la organización de servidores diferentes, etc. y, por lo tanto, necesitarán diferentes valores en la clave de implementación. contenidos (reglas de ubicación, reservas de recursos, etc.), lo que hace que usar un solo archivo para todo sea demasiado complicado".

@vovimayhem Lamento ser franco, pero eso no tiene tanto sentido como usar un solo archivo de composición con sustitución de variables usando un env_file. Preferiría usar el formato env_file ya que esto también hace que sea mucho más fácil para mí proporcionar pilas como entrega a mis clientes y capacitarlos para actualizar un solo archivo vars de estilo ini que meterse con un archivo de composición (que NO no quiero).

Las configuraciones de servicio son una gran adición, pero no parecen útiles para la interpolación del tiempo de implementación (por ejemplo, $TAG).

Si las variables de entorno son compatibles, entonces sea consistente en los mecanismos utilizados para resolverlas en todas las herramientas. La implementación de la pila parece elegir ser inconsistente, sin cambiar fundamentalmente los comportamientos de las variables de entorno. Los secretos y las configuraciones de servicio son mejores alternativas a algunos usos de las variables de entorno, pero no se incluyen.

Parece que no lo entiendes @vovimayhem. No estoy hablando de pasar envs a contenedores; que funciona como se esperaba. Lo que quiero decir es usar un env_file que se analiza durante stack deploy como lo fue durante compose up .

@ntwrkguru Pensé que esta nueva función te ayudaría... Lamento mucho que no sea así.

Esto todavía funciona como una alternativa;

$ echo 'BAR=worked' > ./.env

$ export $(cat .env) && docker stack deploy testing -c -<<'EOF'
version: '3'
services:
  simple:
    image: nginx:alpine
    environment:
      FOO: ${BAR}
    env_file: .env
EOF

$ docker inspect testing_simple -f '{{json .Spec.TaskTemplate.ContainerSpec.Env}}'
["BAR=worked","FOO=worked"]

@thaJeztah , de hecho lo hace. Tengo una tarea en mi libro de jugadas para generar un archivo de entornos, pero falta el punto más importante. Esto solía ser posible con compose y ahora no es posible con stack . En mi opinión, eso es una regresión. Además, en su ejemplo, todavía está pasando una variable de entorno al contenedor. Puedo hacer eso con los env_files hoy; el problema es analizar env_file durante la operación stack deploy -c docker-compose.yml .

Esto es especialmente doloroso ya que stack ya no admite múltiples archivos de composición, de lo contrario, uno podría simplemente usar un archivo de composición secundario por entorno. Para hacerlo de esa manera, se requiere construir el archivo de pila a partir de los archivos de composición, introduciendo otro paso. Entonces, de cualquier manera que lo mires, pasamos de un proceso de un solo paso a un proceso de varios pasos para lograr el mismo resultado final.

Además, FWIW, el configs es realmente inferior en mi experiencia para configuraciones reales. Estaba imaginando (esperando) poder tener /application/config.conf en la fuente. Actualice ese archivo, confirme, empuje y CI volvería a implementar la pila con la nueva configuración. Eso no es posible sin algún tipo de piratería para cambiar el nombre del archivo o algún otro mecanismo. Seguramente podemos hacer una suma de verificación del archivo, como mínimo, o buscar cambios de contenido y actualizar en función del archivo en sí. Con todo, parece que estamos retrocediendo. Agregue el soporte para K8 ahora y me hace preguntarme si el enjambre simplemente languidecerá en la vid hasta que pierda suficiente uso como para dejarlo caer silenciosamente.

Además, FWIW, las configuraciones son realmente inferiores en mi experiencia para configuraciones reales. Estaba imaginando (esperando) poder tener /application/config.conf en fuente. Actualice ese archivo, confirme, empuje y CI volvería a implementar la pila con la nueva configuración. Eso no es posible sin algún tipo de piratería para cambiar el nombre del archivo o algún otro mecanismo.

@ntwrkguru La solución simple es cambiar no el nombre del archivo, sino el nombre de la configuración en sí. Empleé un esquema de versión para mis nombres de configuración, por ejemplo, config_v1 , config_v2 , ..

Así que recuerde actualizar esa versión después de cambiar el archivo de configuración.

services:
  app:
    [...]
    configs:
      - source: config_v2
      - target: /config.yml

configs:
  config_v2:
    file: ./config.yml

Entiendo el razonamiento detrás de no tener configuraciones y secretos versionados todavía, por lo que personalmente estoy de acuerdo con esta solución (fácil).

Gracias @djmaze , pero en última instancia es algo ridículo cuando hay un seguimiento de versión inherente integrado en cada sistema de control de fuente. Además, gracias por el enlace; Ahí también comenté. No veo por qué Docker se preocupa por la versión que no sea la actual. La única razón por la que pude ver que es necesario para la versión de estos es para la reversión, pero también se deben rastrear toneladas de cosas allí de todos modos, entonces, ¿qué es un par más? (dice el chico que no tiene que escribir el código) :-)

Prueba esto:
echo "$(docker-compose -f stack.yml config 2>/dev/null)" | docker stack deploy -c- stack_name

Utiliza docker-compose para analizar el archivo de configuración, sustituyendo env vars, elimina las advertencias de la salida y luego las canaliza a docker stack deployment a través de stdin.
Reemplace '-f stack.yml' con el nombre de su archivo de configuración u omítalo para usar el docker-compose.yml predeterminado.

+1

Un año después y todavía tenemos que hackear esto para que funcione. A partir de la versión 17.09.1, docker stack deploy -f compose.yml ni siquiera sustituirá el uso de variables de shell conocidas.

$ printenv | grep PORTAINER
PORTAINER_VER=1.14.3
portainer:
    image: "portainer/portainer:${PORTAINER_VER}"
$ sudo docker stack deploy -c /tmp/docker/jedi-core.yml --with-registry-auth --prune --resolve-image always jedi-core
Updating service jedi-core_redis_server (id: 0csjyandro713y13ncitk6c0k)
Updating service jedi-core_api-gateway (id: gzcz2eturuxqkjojsc9e6954l)
Updating service jedi-core_auto_results_api (id: tw43c6e0x98q6f0m2g0zttwhf)
Updating service jedi-core_auto_results_api_mongo (id: qpwpypyzd9aigpa71xgxxdzcp)
invalid reference format

Cualquier variable para etiquetas producirá invalid reference format .

Un año después y todavía tenemos que hackear esto para que funcione. A partir del 17.09.1, docker stack deployment -f compose.yml ni siquiera sustituirá el uso de variables de shell conocidas.

ver Cómo mantener las variables de entorno al usar SUDO

$ export PORTAINER_VER=1.14.3
$ printenv | grep PORTAINER
PORTAINER_VER=1.14.3

$ sudo printenv | grep PORTAINER

$ sudo -E printenv | grep PORTAINER
PORTAINER_VER=1.14.3


$ cat > docker-compose.yml <<'EOF'
version: '3'
services:
  portainer:
    image: "portainer/portainer:${PORTAINER_VER}"
EOF


$ sudo -E docker stack deploy -c docker-compose.yml foobar
Creating network foobar_default
Creating service foobar_portainer

$ sudo docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                        PORTS
vt4h0g8yygcg        foobar_portainer    replicated          1/1                 portainer/portainer:1.14.3   

Gracias, pero ¿alguna palabra sobre simplemente admitir la sustitución de variables de un archivo?

[editar] Esto no debería ser un problema (pero podría serlo) ya que estoy usando Ansible para realizar la tarea con become: yes , pero el usuario sigue siendo el mismo usuario que obtiene las variables del entorno.

No puedo creer que esto no sea posible. Nos gustaría mantener un solo archivo de pila y poder cambiar las opciones de implementación usando variables dinámicas.

Esto funcionaría pero es feo y un truco:

echo "$(docker-compose -f stack.yml config 2>/dev/null)" | docker stack deploy -c- stack_name

He estado jugando con esto durante muchas horas y parece que estoy haciendo un trabajo de secuencia de comandos en segundo plano (usaré CI para hacer esto) para crear un archivo DAB a partir de estas diversas piezas. Sería bueno tener una herramienta docker que hiciera esto... :-) ¿Quizás agregar un --env-file version.env agregado a docker-compose bundle ?

En mi caso de uso, quiero usar un "manifiesto" version.env para rastrear y controlar las versiones de contenedores/imágenes que componen una plataforma. Mi proceso se ve así:

  • Actualizar archivo .env
  • Fuente .env archivo para llenar las variables de shell
  • Ejecutar docker-compose -f stack.yml config > docker-compose.yml
  • Ejecute docker-compose pull para registrar los resúmenes de imágenes
  • Ejecutar docker-compose bundle -o stack.version.dab archivo DAB

En este punto, idealmente podría docker deploy --host manager.swarm.com --bundle-file stack.version.dab --with-registry-auth --resolve-image always stack-name , pero entiendo que ahora no es posible. En este caso, enviaría el archivo DAB al administrador y ejecutaría docker deploy .

¿Es este el flujo de trabajo que Docker tenía en mente @thaJeztah? ¿Hay una mejor manera?

[editar] Esto no funciona ya que un DAB ignora las directivas volume: , network: y deploy: . He optado por simplemente obtener un archivo env en el shell, reconstruir un archivo de composición temporal y luego implementarlo.

Me encantaría que los archivos .env se leyeran de forma predeterminada como en Docker Compose y se agregara --env-file (abreviatura -e ) para que docker stack deploy puedan anularse variables de entorno y los valores predeterminados del archivo .env .

+1
Sería bastante conveniente leer el .env en primer lugar como lo hace docker-compose.
Ya sea de forma predeterminada o simplemente pase el archivo env como parámetro en la línea de comando de la pila acoplable.

Las dos soluciones alternativas ya mencionadas (_encuéntrelas también a continuación_) parecen funcionar, aunque un poco feas en comparación con la 'solución' propuesta.

_echo "$(docker-compose -f stack.yml config 2>/dev/null)" | docker stack deployment -c- stack_name_

_env $(cat .env | grep ^[AZ] | xargs) docker stack deployment --compose-file docker-compose.yml [NOMBRE_PILA]_

Agregaría que tener docker-compose instalado solo para poder procesar estas variables también puede ser bastante peligroso en realidad.

Si alguien implementa la pila usando docker-compose up -d por error en lugar de usar docker stack deployment, lo más probable es que provoque errores en las aplicaciones y daños en los archivos.

Tener interpolación de variables de entorno en la implementación es la mejor solución para la integración continua.

Un problema con el uso de '.env' es que se superpone con nombres de archivo similares utilizados, por ejemplo, por Ruby on Rails, tener la capacidad de especificar un archivo de entorno por argumento es superior.

Las sugerencias de @ntelisil están bien tomadas, podrían ser complementadas o modificadas por:

https://unix.stackexchange.com/questions/294835/replace-environment-variables-in-a-file-with-their-actual-values :

Podrías usar envsubst (parte de gnu gettext):
envsubst < archivo de entrada

Solía:

$ envsubst < docker-compose.yml-template > docker-compose.yml

Y funcionó bien, pero necesitaba agregar 3 Mb más o menos a mi contenedor.

Bonito @rnickle , pero aún "incorrecto" en comparación con Docker que puede hacer esto de la forma en que solía hacerlo. Parece (y por favor, los amigos de Docker, corríjanme si me equivoco) que hay muy poco esfuerzo para entrar en modo enjambre desde el anuncio de la compatibilidad con K8, por lo que dudo que se aborde alguna de estas regresiones.

Y funcionó bien, pero necesitaba agregar 3 Mb más o menos a mi contenedor.

Si las variables de entorno están configuradas, docker slack deploy ya debería interpolarlas

en comparación con Docker que puede hacer esto de la forma en que solía hacerlo.

Docker nunca tuvo esta función; ventana acoplable componer tenía; docker compose y docker stack deployment comparten el _formato de archivo_ pero no necesariamente todos los comportamientos del software en sí.

que hay muy poco esfuerzo para entrar en modo enjambre desde el anuncio del soporte de K8

El manejo de archivos de Compose se realiza en el lado del cliente y se usa tanto para k8s como para swarmkit, por lo que nada se ralentiza en esta área, aparte de "no hay mucho que podamos hacer en un momento dado".

Para aquellos que esperan esa característica; la próxima versión tendrá soporte para múltiples archivos de redacción por docker stack deploy , por lo que si actualmente está usando esa función en docker compose: la próxima versión de docker también admitirá esto

Dejando de lado la semántica, gracias por la actualización. Cuando digo Docker, no me refiero necesariamente al demonio o al motor, sino a la empresa que crea las herramientas. La génesis del comentario acerca de que hay poco esfuerzo realmente se deriva del hecho de que el modo de enjambre ha estado fuera durante más de un año y todavía está MUY por detrás de donde estábamos con un solo nodo usando composición.

Puedo apreciar que son diferentes, pero usan el mismo formato de archivo, pero eso en realidad genera más confusión y puede decepcionar cuando los usuarios descubren que tienen que intercambiar características para usar swarm. Eso y el hecho de que los archivos DAB TODAVÍA se enumeran como experimentales. Desafortunadamente, tomamos la decisión de usar el modo enjambre en un gran proyecto, o ni siquiera me importaría. Afortunadamente, no volveremos a cometer ese error.

[editar]

Si las variables de entorno están configuradas, Docker Slack deployment ya debería interpolarlas

Hacer esto en un entorno de CI es un verdadero dolor de cabeza. Esencialmente, terminé instalando compose, obteniendo los envvars, lavando el archivo de composición (después de extraer las imágenes) y luego escupiendo un nuevo archivo de composición para usar con stack deploy . (Y ni siquiera comenzaré con lo doloroso que es cuando :latest no significa :latest en modo enjambre, ya que este problema se trata específicamente de la interpolación de variables).

_EDITAR: Espero que esta publicación no parezca agresiva. Me encanta el concepto de Docker Stack y creo que toda la suite Docker está bastante bien soportada. Simplemente parece que Docker (la organización) actualmente no ve sus productos de la misma manera que los usuarios, lo cual es desafortunado y parece ser la causa de la mayoría de los problemas con los que me he encontrado al usar Compose y Stack._

Docker nunca tuvo esta función; ventana acoplable componer tenía; docker compose y docker stack deployment comparten el formato de archivo, pero no necesariamente todos los comportamientos del software en sí.

Siento que esta declaración revela una desconexión fundamental entre la forma en que los desarrolladores y los usuarios de Docker ven estos productos. Como usuario, ya sea que esté trabajando con Docker Engine, Docker Compose o Docker Swarm, todo es Docker y debería comportarse de manera consistente en la medida de lo posible.

Mi comprensión del propósito de estos productos es:

  • Docker Engine es para construir y ejecutar contenedores individuales
  • Docker Compose es para ejecutar un conjunto de contenedores en desarrollo
  • Docker Stack es para implementar contenedores en producción

Uno de los puntos clave de venta de Docker (y de los contenedores en general) es la fácil reutilización de la misma aplicación en múltiples entornos. Por lo tanto, Compose debe ser aditivo a Engine y Stack debe ser aditivo a Compose. En particular, dado que comparten el mismo formato de archivo, Stack no es compatible con las funciones de Compose, lo que genera confusión para los desarrolladores y una mayor complejidad en los procesos de CI.

No diría que componer es para desarrollo y pila para producción, necesariamente. Considero que componer es para una aplicación o "sistema" de múltiples contenedores y apilar para implementaciones de múltiples hosts usando el modo de enjambre como programador/orquestador. De lo contrario, su comentario es 100% acertado. También estoy frustrado (si no fuera obvio por mis otros comentarios) que hay una desconexión entre los desarrolladores y los usuarios en cuanto a cómo se utilizan los productos.

Oh, vaya. Me uní a la confusión y el dolor mientras evaluaba el enjambre docker para un gran proyecto también.
Los secretos son todos diversión y juegos, solo que no todas las imágenes acoplables externas admiten la lectura de secretos de archivos. No quiero modificar para cada uno de ellos y colocar una imagen personalizada. Podría usarlos para mis proyectos, sí, pero para proyectos externos sería imposible.
Entonces eso deja variables env. Pero bueno, ¡se comportan de manera diferente de componer a apilar! Imagina mi sorpresa cuando noté que realmente no funcionan.
¿Cómo es posible tener docker stack sin soporte env? En mi opinión, lo mejor sería --env-file=dev.env , para que no interfiera con otros archivos env... pero el soporte para esto es horrible. Desafortunadamente, debo volver a k8s, ya que la pila que no tiene esto desde el principio podría resultar ser una elección horrible durante la producción, quién sabe cuántas otras cosas faltarán.

Han pasado dos años y seguimos así... No quiero parecer maleducado, pero ¡vamos! ¡Es cuestión de reutilizar un poco de código de docker-compose!

Otro problema similar con el que me encontré es que incluso si usa env_file, el comportamiento aún no es exactamente el mismo.

Uso env_file para cargar rutas especificadas desde la raíz del proyecto, pero mi archivo de redacción está en un subdirectorio diferente. Para iniciar con docker-compose, solo uso --project-directory . -f ruta/hacia/docker-compose.yml

docker stack no me permite especificar el directorio del proyecto, lo que hace que todos mis env_files no se carguen.

Cambiar env_file a "../../path/to/envrc" no funciona con docker-compose, ya que estos archivos deben estar dentro del directorio raíz del proyecto

+1

+1

+1 esto sería muy útil. No veo un inconveniente realmente.

Es increíblemente tonto que la ventana acoplable no admita esto todavía.

+1 @joao-fidalgo Definitivamente lo es.

+1

Acabo de encontrarme con lo mismo que estamos probando enjambre. He leído todos los mensajes en varios hilos y me siento extremadamente frustrado. En mi opinión, @ntwrkguru y otros hicieron algunos puntos realmente buenos y argumentos sólidos. Espero que podamos considerarlos para incluir esta función; los hacks no lo cortarán.

archivo .env

export MYSQL_USER=user

source .env && docker stack deploy

También funcionará con docker-compose up para bash

archivo .env

export MYSQL_USER=user

source .env && docker stack deploy

También funcionará con docker-compose up

Eso solo funcionaría para bash y no para otros shells.

Esto me confundió como un loco. Mi aplicación aparecería usando docker-compose, pero no con docker stack deployment. Al menos debería haber un descargo de responsabilidad destacado en los documentos.

Pero en mi opinión, esto es un error y está degradando la experiencia de la ventana acoplable.

Necesitamos una respuesta sobre esto.

Casi 2 años y nadie lo ha recogido... no aguantes la respiración @jorgelimafeitosa

No creo que la CLI alguna vez agregue soporte para .env . El comando docker stack deploy se creó originalmente teniendo en cuenta los archivos del paquete de aplicaciones distribuidas (de ahí la opción --bundle-file ). Los archivos DAB fueron generados por Docker Compose con el comando docker-compose bundle . .env y otras características de Compose serían manejadas por docker-compose , antes de pasar a docker stack deploy . El soporte directo para archivos Compose en docker stack deploy siempre fue más un compromiso.

La promesa original de los archivos DAB ahora vive en la aplicación Docker, que tampoco procesa .env .

Mis desarrolladores usan docker-compose config para preprocesar proyectos de Docker Compose antes de pasarlos a docker stack deploy . Puedes hacer esto en una línea con:

docker stack deploy -c <(docker-compose config) stack-name-here

De esa manera, todas las funciones de Docker Compose, incluido el procesamiento .env , se aplican por completo.

@kinghuang Intenté su solución, pero no funcionó. "docker-compose config" produce la salida correcta en el mismo directorio, pero "docker stack deployment -c docker-compose.yaml my_stack" no sustituirá las variables del .env. ¿Qué me estoy perdiendo? Esta es la versión 18.09.0 de Docker, compilación 4d60db4.

@kinghuang Intenté su solución, pero no funcionó. "docker-compose config" produce la salida correcta en el mismo directorio, pero "docker stack deployment -c docker-compose.yaml my_stack" no sustituirá las variables del .env. ¿Qué me estoy perdiendo? Esta es la versión 18.09.0 de Docker, compilación 4d60db4.

docker stack deployment -c <(docker-compose -f docker-compose-frpc-swarm-traefik.yml config) traefik

@kinghuang

abrir /dev/fd/63: no existe tal archivo o directorio

ADVERTENCIA: Algunos servicios (proyecto1, proyecto2) usan la tecla 'implementar', que será ignorada. Compose no admite la configuración de 'implementación': use docker stack deploy para implementar en un enjambre.

@kinghuang
Solo el entorno raíz no informará un error.

La compatibilidad .env y env_file no siempre tiene sentido en un entorno de implementación/producción. No necesita acceso directo al sistema de archivos para ninguna de las otras funciones de Docker Swarm. Por lo tanto, un diseñador/operador responsable de ese sistema no querría darle la posibilidad de volcar archivos de entorno en el sistema de archivos.

En teoría, Swarm podría admitir la carga automática de secretos en el entorno, pero consulte https://github.com/moby/moby/issues/30866#issuecomment -278924983 para saber por qué podría no ser una buena idea en términos de seguridad.

Lo que puede hacer hoy es usar secretos y cargarlos en el entorno de su aplicación cuando se ejecuta el contenedor. Eso le da control sobre dónde se pueden ver los valores del entorno secreto.

+1
La implementación de la pila docker realmente debería ser compatible con --env-file.
Yo mismo estoy luchando con la reutilización del mismo archivo .yml para implementar diferentes pilas para entornos de desarrollo/prueba/producción y no quiero lidiar con algunas exportaciones/abastecimiento complicados de variables de entorno antes de implementar la pila. Esto es muy propenso a errores (y también es un fastidio recordar los comandos exactos cada vez).
En mi caso particular, por ejemplo, quiero establecer diferentes nombres de índice (elasticsearch) por entorno, pero el resto de la configuración permanece igual. Esto no tiene nada que ver con "secretos" como se mencionó en publicaciones anteriores.
Parece haber una necesidad real de --env-file para la implementación de la pila docker según el historial de comentarios anterior, pero lamentablemente los desarrolladores de Docker no parecen ver eso.

En mi entorno de enjambre, me decidí por algunas soluciones:

  • secrets/configs, que estoy usando para cargar archivos de configuración y certificados.
  • Después de ver una demostración del entorno de desarrollo de Azure en el que tenían un script de interpolación de variables que ejecutaban antes de enviar un archivo de composición, escribí el mío y lo puse en mi flujo de lanzamiento de GitLab.

Simplemente especifique el archivo .env en su docker-compose.yml y funcionará:

env_file:
  - .env

Consulte https://stackoverflow.com/questions/44694640/docker-swarm-with-image-versions-externalized-to-env-file

Una solución en powershell para usar en Windows con el fin de analizar el archivo .env antes de llamar a la ventana acoplable:

switch -regex -file "./.env" { "^\s ([^#].+?)\s =\s (. )" { $nombre,$valor = $coincidencias[1..2]; Elemento de conjunto "env:$nombre" $valor}}

Muy inspirado en el análisis de archivos .ini: https://stackoverflow.com/questions/417798/ini-file-parsing-in-powershell

Otra solución es: set -a && . .env && set +a && docker stack deploy... .

Esto es ridículo. Acabo de pasar todo el día tratando de hacer que esto funcione. Al menos se necesita un descargo de responsabilidad en algún lugar de los documentos de que .env no se lee con los comandos docker stack .

@cjancsar Lo hacen. La documentación dice:

Importante: la función de archivo .env solo funciona cuando usa el comando docker-compose up y no funciona con docker stack deployment

Sin interes. ¿Qué hace la gente actualmente cuando está en modo de enjambre y quiere actualizar su nueva imagen acoplable, por ejemplo, app plication:v1 a app plication:v2 , mismo servicio (nada más cambió)?

Esta es la razón por la que llegué a este problema. Por eso estoy interesado.

Actualmente en docker-compose, es trivial lograr que la automatización interactúe con el archivo sin seguimiento de control de fuente . env para actualizar la versión de la imagen, luego docker-compose up -d

A menudo utilizo el sha de confirmación como una versión de la imagen de la ventana acoplable para implementaciones de 'puesta en escena' (etiquetas de git utilizadas para lanzamientos reales después de suficientes ciclos de prueba), por lo que no es realmente posible enviar la nueva versión de la imagen al control de código fuente.

¿Es posible actualizar un secreto de docker (aunque en realidad no es un secreto) como solución alternativa? ¿Es eso lo que hace la gente, o hay algo más que se hace?

Les pido a los futuros visitantes de este número, que realmente obtengan una mejor práctica actual, ya que la funcionalidad que estaban buscando no existe (¿todavía?).

Hola, estoy ocupado investigando la implementación de pilas para su uso en canalizaciones de CI/CD, poder usar un archivo .env sería muy útil, ¿algún comentario sobre si esta opción se introducirá en alguna etapa?

Parece que la recomendación oficial es, de hecho, migrar su código de imagen para admitir la lectura de este tipo de variables desde un archivo de texto secreto, conservando la capacidad de leerlas también desde variables ambientales para compatibilidad con versiones anteriores que no sean de pila/enjambre.

El ejemplo usa un secreto por archivo de texto, lo que evita tener que analizar el archivo .env anterior.

Parafraseado de la documentación en https://docs.docker.com/engine/swarm/secrets/#use -secrets-in-compose :

services:
   db:
     image: mysql:latest
     environment:
       MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD_FILE: /run/secrets/db_password
     secrets:
       - db_root_password
       - db_password

secrets:
   db_password:
     file: db_password.txt
   db_root_password:
     file: db_root_password.txt

suspiro

Esto debería quedar más claro en la documentación. Aunque se menciona que .env no es compatible en la sección Sustitución de variables según @lengxuehx , no se menciona que env_file se ignora para las implementaciones de pila.

Puedo confirmar que la solución propuesta por @kinghuang funciona y no excluye la clave de implementación como dijo alguien.

docker stack deploy -c <(docker-compose config) stack-name-here

Esto debería quedar más claro en la documentación. Aunque se menciona que .env no es compatible en la sección Sustitución de variables según @lengxuehx , no se menciona que env_file se ignora para las implementaciones de pila.

Puedo confirmar que env_file se usa y funciona para implementar el comando de pila, exactamente como lo hace docker compose.

docker version
Client: Docker Engine - Community
 Version:           19.03.4
 API version:       1.40
 Go version:        go1.12.10
 Git commit:        9013bf5
 Built:             Thu Oct 17 23:44:48 2019
 OS/Arch:           windows/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.4
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.10
  Git commit:       9013bf5
  Built:            Thu Oct 17 23:50:38 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

Para resumir, para personas como yo, que han leído esto hasta ahora:

  • docker stack deploy admite "Sustitución de variables", pero debe configurar las variables de entorno desde el archivo .env de alguna manera. Varias opciones se han explicado anteriormente. Una de las mejores soluciones es usar docker-compose config como preprocesador.
    Entonces puedes crear tu pila con docker stack deploy -c <(docker-compose config) STACK_NAME .
  • Aunque Docker introdujo las capacidades de configuración y secretos , tienen sus casos de uso, pero no harán lo mismo que "Sustitución de variable".
  • El parámetro $# env_file docker-compose.yml establecerá las variables de entorno en el contenedor creado y no en el archivo docker-compose.yml en sí mismo (y, por lo tanto, no se puede usar como una alternativa a " Sustitución de variables").

Actualizar:

Fui corregido por @thaJeztah.

Docker no admite la sustitución de variables mediante la implementación de la pila docker y ninguna de las soluciones propuestas funciona.

docker stack deploy admite la sustitución de variables, pero no evalúa el archivo .env ; en el ejemplo siguiente, HELLO_VERSION se establece en linux y el servicio utilizará la etiqueta hello-world:linux (en lugar de la predeterminada hello-world:latest )

HELLO_VERSION=linux docker stack deploy -c docker-compose.yml mystack
Creating network mystack_default
Creating service mystack_hello

docker service inspect --format '{{.Spec.TaskTemplate.ContainerSpec.Image}}' mystack_hello
hello-world:linux<strong i="14">@sha256</strong>:d073a5775c0b99d653c413161a8ed0e9685061afe697931d30eddf6afeef40f6

Dicho esto, aún puede usar variables de entorno usando el parámetro env_file en su archivo docker-compose.yml

El env_file tiene un propósito diferente (y es el equivalente a docker run --env-file ); la opción env_file especifica qué env-vars establecer en el contenedor que se crea, pero no se usa en el archivo de composición en sí (y no se usa para sustituir variables en el archivo de composición antes de implementar la pila).

Tuve el mismo problema junto con otras ligeras diferencias entre docker-compose y docker stack.
Terminé creando https://github.com/egyel/dcsh script/tool ​​para manejar este problema con tuberías.

image
Hola a todos, esto me ayudó a poner env_file en mi docker-compose:

env_file: /path/to/env/file
no

env_file:
  - /path/to/env/file

acabo de ver esto en otra publicación y solo puedo especular por qué funciona (igual que su especulación), pero necesitamos confirmación de por qué esto funciona como docker mencionado explícitamente en el docu que env_file no funciona.

Tengo entendido que los archivos env no se pueden usar para llenar marcadores de posición en
el archivo docker-stack.yml pero aún se pueden proporcionar a los contenedores.
Tenga en cuenta que lo que está haciendo no le permite establecer el nombre de la imagen desde
el archivo env por ejemplo.

El domingo 17 de mayo de 2020 a las 06:08 raphyphy [email protected] escribió:

[imagen: imagen]
https://user-images.githubusercontent.com/30310576/82135555-a1e4be00-9836-11ea-9df4-a1b82e014b0e.png
Hola a todos, esto me ayudó a poner env_file en mi docker-compose:

env_file: /ruta/al/env/archivo
no

archivo_env:

  • /ruta/a/env/archivo

acabo de ver esto en otra publicación y solo puedo especular por qué funciona
(igual que su especulación) pero necesitamos confirmación de por qué esto es
trabajando como docker mencionado explícitamente en el docu que env_file no
trabajo.


Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/29133#issuecomment-629740002 , o
darse de baja
https://github.com/notifications/unsubscribe-auth/ABHLQMCARDQGJQIBWCQKAYLRR5PMHANCNFSM4CYRHCTA
.

La solución docker-compose mencionada anteriormente:

docker stack deploy -c <(docker-compose config) stack-name-here

tiene la desventaja (para mí) de que cosas como los archivos .env y, especialmente, los archivos docker-compose.override.yml son normalmente una parte más importante de mi entorno de desarrollo . Realmente no quiero que se traigan cuando se implemente en producción.

Terminé teniendo un docker-compose-production.yml separado en el que controlé las cosas con cuidado, aunque eso implicaba cierta duplicación.

No creo que la CLI alguna vez agregue soporte para .env . El comando docker stack deploy se creó originalmente teniendo en cuenta los archivos del paquete de aplicaciones distribuidas (de ahí la opción --bundle-file ). Los archivos DAB fueron generados por Docker Compose con el comando docker-compose bundle . .env y otras características de Compose serían manejadas por docker-compose , antes de pasar a docker stack deploy . El soporte directo para archivos Compose en docker stack deploy siempre fue más un compromiso.

La promesa original de los archivos DAB ahora vive en la aplicación Docker, que tampoco procesa .env .

Mis desarrolladores usan docker-compose config para preprocesar proyectos de Docker Compose antes de pasarlos a docker stack deploy . Puedes hacer esto en una línea con:

docker stack deploy -c <(docker-compose config) stack-name-here

De esa manera, todas las funciones de Docker Compose, incluido el procesamiento .env , se aplican por completo.

Esto funciona de maravilla, tenga en cuenta que si su archivo de redacción no tiene el nombre "docker-compose.yml", su comando debe incluir el nombre real del archivo de redacción.

docker stack deployment -c <(docker-compose -f CUSTOM-COMPOSE-FILENAME.yml config) CUSTOM-STACK

¡ CUIDADO con el <(docker-compose -f CUSTOM-COMPOSE-FILENAME.yml config HACK! ¡La salida de docker-compose config y docker-compose -f myfile.yml config NO es necesariamente la misma! Este último a veces envuelve las variables env entre comillas adicionales, ¡así que la salida será incorrecta!

Ejemplo:

environment:
  SERVER_URL: '"xxx"'

en vez de

environment:
  SERVER_URL: xxx

¿Ya se ha rastreado este problema en alguna parte?

¿Fue útil esta página
0 / 5 - 0 calificaciones