Moby: 1.13의 `docker stack deploy`는 `docker-compose up`이 하는 것처럼 `.env` 파일을 로드하지 않습니다.

에 만든 2016년 12월 05일  ·  93코멘트  ·  출처: moby/moby

docker stack deploy --compose-file 함수를 테스트하기 위해 샘플 docker-compose.yml 중 하나를 로드합니다.

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:

image 서비스 nginxphp $ 섹션에서 ${DOCKER_USER} 를 사용하여 환경 변수에서 도커 ID를 가져왔습니다. 그리고 docker-compose up 를 사용하면 .env 파일을 기본 envvar 파일로 로드합니다. 그 내용은 다음과 같습니다.

DOCKER_USER=twang2218

그러나 docker stack 를 사용하여 이 docker-compose.yml $ 를 배포하면 다음 오류가 발생합니다.

$ 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

보시다시피 docker stack deploy 명령이 .env 파일을 로드하지 않았기 때문에 ${DOCKER_USER} 가 빈 문자열로 대체되어 이미지 이름이 유효하지 않게 되었습니다.

.env 파일이 로드된 경우 최종 이미지 이름은 twang2218/lnmp-php:v1.2 여야 합니다.

다음과 같이 명령을 실행하면 환경 대체가 실제로 작동합니다.

$ 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

docker service inspect 명령으로 작동하는지 확인할 수 있습니다.

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

이미지 이름은 twang2218/lnmp-php:v1.2 입니다. 맞습니다.

docker-machine 를 통해 docker 1.13.0-rc2를 설치한 Digtial Ocean droplet에서 이 기능을 테스트했습니다.

버전은 다음과 같습니다.

$ 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

다음은 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

가장 유용한 댓글

@whoan 이것을 해결 방법으로 사용하고 있습니다.

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

그렇게하면 변수가 터미널 창에 걸리지 않습니다.

모든 93 댓글

이것은 의도적으로 설계된 것입니다. .env 지원은 파일 형식이 아니라 Compose의 기능입니다.

향후 릴리스를 위해 이것을 추가하는 것에 대해 논의할 수 있지만 이것이 정말로 최선의 선택인지는 모르겠습니다.

.env 지원은 Compose에서 매우 유용하며 많은 compose 파일에서 사용했습니다. docker-compose.yml 파일의 동적 부분과 정적 부분을 구분합니다. 기본적으로 .env 로드를 사용하면 다른 환경에 대해 다른 .env 파일을 제공하고 docker-compose.yml 및 관련 스크립트를 정적으로 유지할 수 있습니다.

동일한 환경 대체 결과를 얻기 위해 docker-compose.yml env_file 또는 environment 를 사용할 수 없습니다. .env 는 가장 쉬운 방법입니다.

그렇지 않으면 .env export 접두사를 붙이고 $# docker-compose.yml 를 로드하기 전에 매번 수동으로 source .env 를 추가해야 하며 추가 단계가 종종 발생하기 쉽습니다. 실수하다.

나는 이것을 눈치 챘다.
Compose와 동일한 방식으로 작동할 것으로 가정/예상했지만 docker deploy 의 경우는 아닙니다.

제 경우에는 .env 파일을 사용하여 스택에 생성할 서비스에 사용되는 민감한 데이터(비밀번호, API 키 등)를 저장하려고 했습니다.

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

이 Compose 파일은 Git에서 체크인되지만 .env 파일은 무시됩니다.

나는 *.dab vs compose 파일의 전체 내용/기록을 따랐고 여러분이 무언가를 피하려고 하거나 더 나은 솔루션을 제안한다고 생각하지만 전체 토론을 추적하지 못했습니다...

여러분 안녕하세요,

도커 버전: v1.13.0-rc4

오류가 발생합니다. 지원되지 않는 옵션 무시: build , Dockerfile에서 빌드를 생성하지 않는다는 의미입니까?

또한 network_mode에 대해 동일한 오류가 발생합니다. 지원되지 않는 옵션 무시: network_mode.

아래는 명령입니다.
DOCKER_IMAGE=akhil123 도커 스택 배포 -c docker-compose.yml foo

미리 감사드립니다.

@akhildangore 직접 관련되지 않은 질문에 대한 문제에 대해 언급하지 마십시오. docker stack deploy 기능은 _설계에 따라_ 빌드를 수행하지 않습니다. 그 이유는 명령이 실행되는 호스트에서 _build_가 수행되어 이미지가 _that_ 노드에서만 사용 가능하기 때문입니다. 해당 이미지를 Swarm에 배포할 때 다른 노드에서 서비스를 시작할 수 없습니다. 서비스를 배포하려면 배포 중인 이미지가 레지스트리에 푸시되었는지 확인하십시오(또는 테스트용으로, 이미지가 무리의 모든 노드에서 사용 가능한지 확인하십시오).

docker deploy 에 대한 이 행동을 지지하는/반대하는 사례/토론이 있습니까?

@vovimayhem .env 파일에 대해 아직 결정이 내려지지 않았지만 작성 파일에 비밀 지원을 추가하는 https://github.com/docker/docker/pull/30144 에 관심이 있을 수 있습니다.

방금 그 토론을 찾았습니다. 훌륭한!

해결 방법으로 bash 기능을 사용하고 있습니다.

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
    )
}

이 호를 구독하는 사람들을 위해; docker-compose 파일에 대한 secrets 지원은 1.13.1 릴리스에 포함될 예정이며, 이는 너무 멀지 않은 미래일 것입니다.

@whoan 이것을 해결 방법으로 사용하고 있습니다.

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

그렇게하면 변수가 터미널 창에 걸리지 않습니다.

.env 파일에서 항목을 로드할 수 있다는 것은 항상 좋은 일입니다. 이제 우회할 수 있는 더 간단한 Docker 비밀 사용 사례를 제외하고 하드코딩하고 싶지 않은 Docker Compose 값이 항상 있습니다. 당신의 리포지토리에.

docker stack deploy 를 사용하여 전체 스택을 배포하고 다음 요구 사항이 있다고 가정해 보겠습니다.

  • 다른 환경에 대해 정확히 동일한 구성을 사용하려는 경우(예: 스테이징 및 프로덕션)

    • 각 환경에 대해 다른 스케일 값이 필요합니다.

.env 파일로 이를 구성할 수 없는 경우 매번 스택을 배포하기 전에 docker-compose.yml 파일을 수동으로 변경해야 합니다. 그렇지 않으면 서비스 규모 값이 다시 1로 되돌아갑니다.

네트워크, 서비스가 수신 대기해야 하는 DNS 구성 등과 같은 것으로 위의 내용을 확장할 수 있습니다.

위의 사용 사례가 타당하다고 생각되는 경우 .env 파일이 docker-compose.yml 와 동일한 디렉토리에 있는 경우 이를 로드하는 PR 초안을 작성할 수 있습니다.

docker stack docker-compose 명령과 약간 다릅니다. 기본적으로 .env 를 읽는 것은 의미가 없다고 생각합니다. docker-compse.yml 도 기본적으로 읽히지 않습니다. 미래에는 기본 배포 소스가 다른 것이 될 가능성이 높기 때문입니다.

stack deploy 를 실행하기 전에 항상 .env 파일을 직접 소싱할 수 있습니다.

$# docker stack deploy #$를 호출하기 전에 . .env $는 도움이 되지 않으며 $variables는 대체되지 않습니다. env .. xargs 트릭만 도움이 되었습니다.
docker run 와 같은 --env-file=FILE 옵션이 있으면 좋을 것입니다.

단지 . docker stack deploy를 호출하기 전에 .env가 도움이 되지 않습니다.

이것은 @C-Pro에 도움이 될 것입니다. .env 파일에 export ... 줄이 있어야 합니다. 또는 export $(cat .env) 하면 대부분의 경우에 효과가 있습니다.

여러분 안녕하세요,
오늘은 docker stack deploy 을(를) 실행하려고 했습니다.
docker-compose.yml 파일:

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

그리고 .env 파일은 같은 디렉토리에 있습니다.

BAR=worked

docker stack deploy -c docker-compose.yml test 시작 후 컨테이너를 검사하고 다음을 얻었습니다.

$ env
BAR=worked
FOO=
...

.env 는 컨테이너에 제공되지만 호스트 시스템에는 제공되지 않는 것 같습니다.
즉, environment 섹션 대신 .env 파일을 사용할 수 있지만 .env 파일을 Variable Substitution과 함께 사용할 수 없습니다.
도커 버전: v17.03

@ddpaimon
환경:
- FOO=${바}

.env 파일은 컨테이너에서만 작동하지만 docker-compose.yml 파일 변수 교체에는 작동하지 않는 것처럼 보입니다.

MAC용 Docker, Docker 버전 17.03.1-ce, 빌드 c6d412e

@realcbb
예. 그러나 컨테이너 내부에서 .env 파일 변수를 사용하려면 environment 섹션에서 해당 변수를 제거해야 합니다.
예를 들어:
docker-compose.yml

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

.env

FOO=filled

컨테이너에서 나는 이것을 얻었다.

$ env
FOO=empty

그러나 docker-compose.yml 의 environment 섹션에서 docker-compose.yml FOO 를 제거하면 다음과 같이 표시됩니다.

$ env
FOO=filled

@ddpaimon
환경에 지정된 환경 변수는 .env 파일에 지정된 이러한 값을 재정의합니다.

@dnephin : .env가 docker compose 파일 형식의 일부가 아니라고 명시했습니다. 그러나 .env 파일 기능은 Compose 파일 버전 3 참조( https://docs.docker.com/compose/compose-file/#variable -substitution)에 설명되어 있습니다.
이것은 .env가 도커 스택 배포에서도 작동해야 한다는 인상을 줍니다.
그 외에도 다른 사람들이 이미 언급했듯이 스택 정의 yaml에서 실제 환경 특정 값을 분리하는 것은 매우 원하고 필요한 기능입니다. 특히 이미지 버전 및 복제를 지정하는 데 사용하려고 합니다.

감사합니다. 문서를 수정하기 위해 https://github.com/docker/docker.github.io/issues/3654 를 열었습니다.

docker stack deploy 는 생성된 파일을 사용할 수 있습니다. 이것은 내 모든 변수에 대해 bash에서 작동하며 비밀도 비밀로 유지합니다.

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

인라인 ENV 변수를 추가 변수 또는 재정의로 추가했습니다. 내 작성 파일은 .env 파일을 참조하며 작동합니다. 도움이 되기를 바랍니다 👍

docker-compose config 의 기능은 이것을 함께 묶는 것입니다.

.env 에 의해 읽히지 않는 docker stack deploy 에 대한 해결책을 찾을 때 이 문제를 발견했습니다. 지원되지 않는 것을 보고 약간 놀랐지만(문서를 명확히 할 수 있음), 작성과 같이 .env 에 대한 지원을 추가하고 싶습니다.

내 사용 사례는 개발, 테스트, 스테이징 환경에서 docker stack deploy 를 사용하고 yml 파일을 동일하게 유지하기 위해 스택 옵션에 환경 변수를 사용한다는 것입니다.

현재 여기에 게시된 해결 방법 중 하나를 사용하고 있지만 .env 파일을 사용하는 것이 선호되는 경로입니다.

친절한 알림: dotenv 파일을 사용하여 API 키, 비밀번호 및 클러스터에 넣을 "민감한" 것으로 간주되는 기타 항목을 저장하려고 할 가능성이 있습니다. 이러한 경우 Docker Secrets 를 사용해야 합니다.

다른 항목의 경우 배포/배포 가능한 환경당 하나의 작성 파일을 제안해도 됩니까? 다른 환경 사이에서 변경되는 대부분의 항목은 사용 가능한 서버, 다른 서버 조직 등이 될 것이므로 deploy 내용에 다른 값이 필요합니다( placement 규칙, resources 예약 등) 단일 파일을 사용하여 모든 것을 너무 복잡하게 만듭니다.

실제로 이 기능을 원합니다. docker 스택 배포를 사용할 때 작성 파일의 변수를 다른 호스트에서 다른 값으로 처리할 수 있습니다.

"다른 경우에는 배포/배포 가능한 환경당 하나의 작성 파일을 갖도록 제안할 수 있습니까? 다른 환경 간에 변경되는 대부분의 내용은 사용 가능한 서버, 다른 서버 조직 등이 될 것이므로 배포 키에 다른 값이 필요합니다. 콘텐츠(배치 규칙, 리소스 예약 등)로 인해 단일 파일을 사용하여 모든 것을 너무 복잡하게 만듭니다."

@vovimayhem 무뚝뚝해서 죄송하지만 env_file을 사용하여 변수를 대체하는 단일 작성 파일을 사용하는 것만큼 의미가 없습니다. 나는 env_file 형식을 사용하는 것을 선호합니다. 이렇게 하면 고객에게 스택을 제공할 수 있고 단일 ini 스타일의 vars 파일을 업데이트하도록 교육하는 것이 compose 파일을 엉망으로 만드는 것보다 훨씬 쉽게 할 수 있기 때문입니다. 원한다).

서비스 구성은 훌륭한 추가 기능이지만 배포 시간 보간(예: $TAG)에는 사용할 수 없는 것 같습니다.

환경 변수가 전혀 지원되지 않는다면 여러 도구에서 환경 변수를 해결하는 데 사용되는 메커니즘에서 일관성을 유지하십시오. 스택 배포는 환경 변수 동작을 근본적으로 변경하지 않고 일관성이 없는 것으로 보입니다. 비밀 및 서비스 구성은 일부 환경 변수 사용에 대한 더 나은 대안이지만 포함하지는 않습니다.

@vovimayhem을 이해하지 못하는 것 같습니다. 나는 envs를 컨테이너로 전달하는 것에 대해 말하는 것이 아닙니다. 예상대로 작동합니다. 내 말은 compose up 동안과 마찬가지로 stack deploy 동안 구문 분석되는 env_file을 사용하는 것입니다.

@ntwrkguru 이 새로운 기능이 도움이 될 거라고 생각했는데... 도움이 되지 않아 너무 슬픕니다.

이것은 여전히 ​​대안으로 작동합니다.

$ 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 , 실제로 그렇습니다. 내 플레이북에 환경 파일을 소싱하는 작업이 있지만 더 큰 요점이 누락되었습니다. 이것은 compose 로 가능했지만 지금은 stack 로 불가능합니다. IMO, 그것은 회귀입니다. 또한 귀하의 예에서는 여전히 환경 변수를 컨테이너에 전달하고 있습니다. 오늘 env_files 로 할 수 있습니다. 문제는 stack deploy -c docker-compose.yml 작업 중에 env_file 를 구문 분석하는 것입니다.

이것은 stack 가 더 이상 여러 작성 파일을 지원하지 않기 때문에 특히 고통스럽습니다. 그렇지 않으면 환경당 보조 작성 파일을 간단히 사용할 수 있습니다. 그렇게 하려면 다른 단계를 도입하여 작성 파일에서 스택 파일을 빌드해야 합니다. 따라서 어떤 방식으로 보든 동일한 최종 결과를 달성하기 위해 단일 단계 프로세스에서 다단계 프로세스로 이동했습니다.

또한 FWIW에서 configs 는 실제 구성에 대한 내 경험에 비추어 볼 때 정말 수준 이하입니다. 소스에 /application/config.conf 가 있을 수 있다고 생각했습니다(희망). 해당 파일을 업데이트하고 커밋하고 푸시하면 CI가 새 구성으로 스택을 다시 배포합니다. 파일 이름이나 다른 메커니즘을 변경하는 해커 없이는 불가능합니다. 최소한 파일을 체크섬하거나 콘텐츠 변경 사항을 검색하고 파일 자체를 기반으로 업데이트할 수 있습니까? 대체로 우리는 거꾸로 가고 있는 것 같습니다. 지금 K8에 대한 지원을 시작하면 떼가 조용히 떨어질 만큼 충분한 사용량을 잃을 때까지 포도나무에서 시들지 않을지 궁금합니다.

또한 FWIW, 구성은 실제 구성에 대한 내 경험에 비추어 볼 때 실제로 하위 수준입니다. 소스에 /application/config.conf가 있을 수 있다고 생각했습니다(희망). 해당 파일을 업데이트하고 커밋하고 푸시하면 CI가 새 구성으로 스택을 다시 배포합니다. 파일 이름이나 다른 메커니즘을 변경하는 해커 없이는 불가능합니다.

@ntwrkguru 간단한 해결 방법은 파일 이름이 아니라 구성 자체의 이름을 변경하는 것입니다. 내 구성 이름에 대해 버전 체계를 사용했습니다(예: config_v1 , config_v2 , ..

따라서 구성 파일을 변경한 후 해당 버전을 기억하십시오.

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

configs:
  config_v2:
    file: ./config.yml

아직 버전이 지정된 구성 및 비밀이 없는 이유 를 이해하므로 개인적으로 현재 이 (쉬운) 해결 방법으로 괜찮습니다.

@djmaze 에게 감사합니다. 하지만 모든 소스 제어 시스템에 고유한 버전 추적 기능이 내장되어 있을 때 수행해야 하는 궁극적으로 어리석은 일입니다. 또한 링크 주셔서 감사합니다. 거기에 나도 댓글을 달았다. Docker가 최신 버전이 아닌 다른 버전에 관심을 갖는 이유를 모르겠습니다. 이것들을 버전화하는 데 필요하다고 볼 수 있는 유일한 이유는 롤백을 위한 것이지만 어쨌든 그곳에서도 수많은 항목을 추적해야 합니다. 그렇다면 몇 가지가 더 있습니까? (코드를 작성할 필요가 없는 사람을 말합니다) :-)

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

docker-compose를 사용하여 구성 파일을 구문 분석하고 env vars를 대체하고 출력에서 ​​경고를 제거한 다음 stdin을 통해 도커 스택 배포에 파이프합니다.
'-f stack.yml'을 구성 파일의 이름으로 바꾸거나 기본 docker-compose.yml을 사용하도록 생략합니다.

+1

1년이 지난 지금도 우리는 이것을 해킹해야 작동합니다. 17.09.1부터 docker stack deploy -f compose.yml 는 알려진 쉘 변수를 사용하여 대체하지도 않습니다.

$ 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

태그에 대한 모든 변수는 invalid reference format 를 생성합니다.

1년이 지난 지금도 우리는 이것을 해킹해야 작동합니다. 17.09.1부터 docker stack deploy -f compose.yml은 알려진 셸 변수를 사용하여 대체하지도 않습니다.

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   

감사합니다. 하지만 단순히 파일에서 변수 대체를 지원하는 방법에 대해 말씀해 주시겠습니까?

[편집] 이것은 Ansible을 사용하여 become: yes 작업을 수행하기 때문에 문제가 되지 않아야 하지만 사용자는 여전히 환경 변수를 제공하는 동일한 사용자입니다.

이게 불가능하다는 게 믿기지 않습니다. 단일 스택 파일을 유지하고 동적 변수를 사용하여 배포 옵션을 변경할 수 있기를 원합니다.

이것은 작동하지만 추하고 해킹입니다.

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

나는 여러 시간 동안 이것을 엉망으로 만들어 왔으며 이러한 다양한 조각에서 DAB 파일을 만들기 위해 백그라운드 스크립트 작업(이 작업을 수행하기 위해 CI를 사용할 것입니다)을 하는 것처럼 보입니다. 이 작업을 수행하는 도커 도구가 있으면 좋을 것입니다... :-) docker-compose bundle--env-file version.env 추가?

제 사용 사례에서는 version.env "매니페스트"를 사용하여 플랫폼을 구성하는 컨테이너/이미지 버전을 추적하고 제어하려고 합니다. 내 프로세스는 다음과 같습니다.

  • .env 파일 업데이트
  • .env 셸 변수를 채우기 위한 소스 .env 파일
  • docker-compose -f stack.yml config > docker-compose.yml 실행
  • docker-compose pull 를 실행하여 이미지 다이제스트를 등록합니다.
  • docker-compose bundle -o stack.version.dab DAB 파일 실행

이 시점에서 이상적으로는 docker deploy --host manager.swarm.com --bundle-file stack.version.dab --with-registry-auth --resolve-image always stack-name 수 있지만 지금은 불가능하다는 것을 알았습니다. 이 경우 DAB 파일을 관리자에게 scp하고 docker deploy 를 실행합니다.

이것이 Docker가 @thaJeztah를 염두에 둔 워크플로입니까? 더 좋은 방법이 있습니까?

[편집] DAB가 volume: , network:deploy: 지시문을 무시하기 때문에 이것은 작동하지 않습니다. 나는 단순히 env 파일을 셸에 소싱하고 임시 작성 파일을 다시 빌드한 다음 배포했습니다.

Docker Compose와 같이 기본적으로 .env 파일을 읽고 docker stack deploy 를 재정의할 수 있도록 --env-file (짧은 -e )를 추가하면 좋겠습니다. .env 파일의 환경 변수 및 기본값.

+1
docker-compose처럼 처음에 .env를 읽는 것이 매우 편리할 것입니다.
기본적으로 또는 env 파일을 docker 스택 명령줄의 매개변수로 전달하십시오.

이미 언급된 두 가지 해결 방법(_아래에서도 찾아보기_)은 제안된 '수정'에 비해 약간 못생겼지만 작동하는 것 같습니다.

_echo "$(docker-compose -f stack.yml 구성 2>/dev/null)" | 도커 스택 배포 -c- stack_name_

_env $(cat .env | grep ^[AZ] | xargs) 도커 스택 배포 --compose-file docker-compose.yml [STACK_NAME]_

이러한 변수를 처리할 수 있도록 docker-compose를 설치하는 것도 실제로 매우 위험할 수 있다고 덧붙였습니다.

누군가 docker stack deploy를 사용하는 대신 실수로 docker-compose up -d를 사용하여 스택을 배포하면 응용 프로그램 오류 및 파일 손상이 발생할 가능성이 큽니다.

배포 시 환경 변수 보간을 사용하는 것이 지속적인 통합을 위한 최상의 솔루션입니다.

'.env'를 사용할 때의 한 가지 문제는 Ruby on Rails에서 사용하는 유사한 파일 이름과 중복되므로 인수로 환경 파일을 지정하는 기능이 더 우수하다는 것입니다.

@ntelisil 의 제안은 잘 받아들여졌으며 다음과 같이 보완하거나 수정할 수 있습니다.

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

envsubst(gnu gettext의 일부)를 사용할 수 있습니다.
envsubst < 파일

나는 사용했다:

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

잘 작동했지만 컨테이너에 3Mb 정도를 추가해야 했습니다.

좋은 @rnickle 이지만 Docker가 이전 방식으로 이 작업을 수행할 수 있는 것과 비교하면 여전히 "해키"입니다. K8 지원 발표 이후 스웜 모드로 들어가는 노력이 거의 없는 것 같아서(그리고 내가 틀렸다면 Docker 친구들이 정정해 주세요.) 따라서 이러한 회귀가 해결될지 의심스럽습니다.

잘 작동했지만 컨테이너에 3Mb 정도를 추가해야 했습니다.

환경 변수가 설정된 경우 docker slack deploy 는 이미 이를 보간해야 합니다.

Docker가 이전 방식으로 이 작업을 수행할 수 있었던 것과 비교됩니다.

Docker에는 이 기능이 없었습니다. 도커 작성이 있었다; docker compose 및 docker stack deploy는 _파일 형식_을 공유하지만 반드시 소프트웨어 자체의 모든 동작은 아닙니다.

K8s 지원 발표 이후 스웜 모드로 들어가는 노력이 거의 없음

Compose 파일 처리는 모두 클라이언트 측에서 수행되며 k8 및 swarmkit 모두에 사용되므로 "주어진 시간에 할 수 있는 일은 너무 많다" 외에는 이 영역에서 속도가 느려지는 것이 없습니다.

그 기능을 기다리는 사람들을 위해; 다음 릴리스는 docker stack deploy 에 대한 여러 작성 파일을 지원하므로 현재 docker compose에서 해당 기능을 사용하고 있다면 다음 docker 릴리스에서도 이 기능을 지원합니다.

의미는 제쳐두고, 업데이트에 감사드립니다. 도커는 데몬이나 엔진이 아니라 도구를 만드는 회사를 의미합니다. 노력이 거의 없다는 의견의 기원은 실제로 swarm-mode가 나온 지 1년이 넘었고 compose를 사용하는 단일 노드에 비해 여전히 뒤쳐져 있다는 사실에서 비롯됩니다.

나는 그들이 서로 다르지만 동일한 파일 형식을 사용한다는 점을 이해할 수 있지만, 이는 실제로 사용자가 Swarm을 사용하기 위해 기능을 교환해야 한다는 사실을 발견했을 때 더 많은 혼란을 야기하고 잠재적으로 실망스럽게 만듭니다. DAB 파일이 여전히 실험용으로 나열되고 있다는 사실. 불행히도 우리는 큰 프로젝트에서 swarm-mode를 사용하기로 결정했습니다. 다행히 다시는 그런 실수를 하지 않을 것입니다.

[편집하다]

환경 변수가 설정된 경우 docker slack deploy는 이미 이를 보간해야 합니다.

CI 환경에서 이 작업을 수행하는 것은 정말 고통스러운 일입니다. 본질적으로 나는 compose를 설치하고, 환경 변수를 소싱하고, compose 파일을 세척하고(이미지를 가져온 후) stack deploy 와 함께 사용할 새 compose 파일을 뱉어냈습니다. (그리고 :latest 가 Swarm 모드에서 :latest 를 의미하지 않을 때 얼마나 고통스러운지에 대해서는 시작조차 하지 않을 것입니다. 왜냐하면 이 문제는 특히 변수 보간에 관한 것이기 때문입니다.)

_EDIT: 이 게시물이 공격적으로 나타나지 않기를 바랍니다. 저는 Docker Stack 개념을 좋아하고 전체 Docker 제품군이 꽤 잘 지원된다고 생각합니다. Docker(조직)는 현재 사용자가 보는 것과 같은 방식으로 제품을 보지 않는 것 같습니다. 이는 불행하고 Compose 및 Stack을 사용하여 내가 겪었던 대부분의 문제의 원인인 것으로 보입니다._

Docker에는 이 기능이 없었습니다. 도커 작성이 있었다; docker compose 및 docker stack deploy는 파일 형식을 공유하지만 반드시 소프트웨어 자체의 모든 동작은 아닙니다.

나는 이 진술이 Docker의 개발자와 사용자가 이러한 제품을 보는 방식 사이의 근본적인 단절을 드러낸다고 생각합니다. 사용자로서 Docker Engine, Docker Compose 또는 Docker Swarm을 사용하든 상관없이 모두 Docker이며 가능한 한 일관되게 작동해야 합니다.

이 제품의 목적에 대한 나의 이해는 다음과 같습니다.

  • Docker 엔진은 개별 컨테이너를 빌드하고 실행하기 위한 것입니다.
  • Docker Compose는 개발 중인 컨테이너 제품군을 실행하기 위한 것입니다.
  • Docker Stack은 컨테이너를 프로덕션에 배포하기 위한 것입니다.

Docker(및 일반적으로 컨테이너)의 주요 판매 포인트 중 하나는 여러 환경에서 동일한 앱을 쉽게 재사용할 수 있다는 것입니다. 따라서 Compose는 Engine에 추가되어야 하고 Stack은 Compose에 추가되어야 합니다. 특히 동일한 파일 형식을 공유하기 때문에 Stack이 Compose의 기능을 지원하지 않으면 개발자에게 혼란을 야기하고 CI 프로세스가 더 복잡해집니다.

나는 compose가 dev를 위한 것이고 stack이 prod를 위한 것이라고 말하지 않을 것입니다. 나는 compose가 스케줄러/오케스트레이터로 swarm-mode를 사용하는 다중 호스트 배포를 위한 다중 컨테이너 응용 프로그램 또는 "시스템" 및 스택을 위한 것으로 봅니다. 그렇지 않으면 귀하의 의견이 100% 정확합니다. 나는 또한 제품이 어떻게 사용되는지에 관해 개발자와 사용자 사이에 단절이 있다는 사실에 좌절했습니다(다른 의견에서 명확하지 않은 경우).

오 와우. 큰 프로젝트를 위해 docker swarm을 평가하는 동안 혼란과 고통에 합류했습니다.
비밀은 모두 재미 있고 게임이지만 모든 외부 도커 이미지가 파일에서 비밀 읽기를 지원하는 것은 아닙니다. 나는 그들 각각에 대해 수정하고 사용자 정의 이미지를 배치하고 싶지 않습니다. 내 프로젝트에 사용할 수는 있지만 외부 프로젝트에는 사용할 수 없습니다.
그래서 env 변수가 남습니다. 하지만 그들은 작성에서 스택에 따라 다르게 행동합니다! 그들이 실제로 작동하지 않는다는 것을 알았을 때 내가 놀랐을 때를 상상해 보십시오.
env 지원 없이 도커 스택을 가질 수 있는 방법은 무엇입니까? 제 생각에는 --env-file=dev.env 가 가장 좋으므로 다른 env 파일을 방해하지 않습니다... 하지만 이에 대한 지원은 끔찍합니다. 불행히도 k8로 돌아가야 합니다. 스택이 처음부터 이것을 놓치면 프로덕션 단계에서 끔찍한 선택이 될 수 있습니다.

2년이 지났지만 우리는 여전히 그러하다... 무례하게 보이고 싶지는 않지만 어서! docker-compose의 약간의 코드를 재사용하는 것이 중요합니다!

방금 만난 또 다른 유사한 문제는 env_file을 사용하더라도 동작이 여전히 정확히 동일하지 않다는 것입니다.

env_file을 사용하여 프로젝트 루트에서 지정된 경로를 로드하지만 내 작성 파일은 다른 하위 디렉토리에 있습니다. docker-compose로 시작하려면 --project-directory를 사용하면 됩니다. -f 경로/to/docker-compose.yml

docker stack 를 사용하면 프로젝트 디렉토리를 지정할 수 없으므로 모든 env_files가 로드되지 않습니다.

env_file을 "../../path/to/envrc"로 변경하면 docker-compose에서 작동하지 않습니다. 이러한 파일은 프로젝트 루트 디렉토리 안에 있어야 하기 때문입니다.

+1

+1

+1 이것은 정말 유용할 것입니다. 정말 단점이 보이지 않습니다.

도커가 아직 이것을 지원하지 않는다는 것은 엄청나게 멍청합니다.

+1 @joao-fidalgo 확실히 그렇습니다.

+1

우리가 떼를 시도하는 것과 같은 일을 겪었습니다. 다양한 스레드의 모든 메시지를 읽었으며 매우 실망했습니다. IMO, @ntwrkguru 와 다른 사람들이 정말 좋은 점과 강력한 주장을 했습니다. 나는 그들이 이 기능을 도입하는 것을 고려할 수 있기를 바랍니다. 해킹은 그것을 자르지 않을 것입니다.

.env 파일

export MYSQL_USER=user

source .env && docker stack deploy

bash의 경우 docker-compose up 에서도 작동합니다.

.env 파일

export MYSQL_USER=user

source .env && docker stack deploy

docker-compose up 에서도 작동합니다.

그것은 bash에서만 작동하고 다른 쉘에서는 작동하지 않습니다.

이것은 나를 미친 듯이 혼란스럽게 했다. 내 앱은 docker-compose를 사용하여 표시되지만 docker 스택 배포에서는 표시되지 않습니다. 문서에는 최소한 면책 조항이 눈에 띄게 표시되어야 합니다.

그러나 IMO는 이것이 버그이며 도커 경험을 저하시키고 있습니다.

이에 대한 답변이 필요합니다

거의 2년이 흘렀지만 아무도 그것을 집어들지 않았습니다...숨 참지 마세요 @jorgelimafeitosa

CLI가 .env 지원을 추가할 것이라고 생각하지 않습니다. docker stack deploy 명령은 원래 분산 응용 프로그램 번들 파일을 염두에 두고 빌드되었습니다(따라서 --bundle-file 옵션). DAB 파일은 docker-compose bundle 명령을 사용하여 Docker Compose에 의해 생성되었습니다. .env 및 기타 Compose 기능은 docker stack deploy 에 전달되기 전에 docker-compose 에 의해 처리됩니다. docker stack deploy 의 Compose 파일에 대한 직접 지원은 항상 타협이었습니다.

DAB 파일의 원래 약속은 이제 .env 도 처리하지 않는 Docker 앱에 있습니다.

개발자가 docker-compose config 를 사용하여 Docker Compose 프로젝트를 docker stack deploy 에 전달하기 전에 사전 처리하도록 했습니다. 다음을 사용하여 한 줄로 수행할 수 있습니다.

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

이렇게 하면 .env 처리를 포함한 모든 Docker Compose 기능이 완전히 적용됩니다.

@kinghuang 솔루션을 시도했지만 작동하지 않았습니다. "docker-compose config"는 동일한 디렉토리에서 올바른 출력을 생성하지만 "docker stack deploy -c docker-compose.yaml my_stack"은 .env의 변수를 대체하지 않습니다. 내가 무엇을 놓치고 있습니까? Docker 버전 18.09.0, 빌드 4d60db4입니다.

@kinghuang 솔루션을 시도했지만 작동하지 않았습니다. "docker-compose config"는 동일한 디렉토리에서 올바른 출력을 생성하지만 "docker stack deploy -c docker-compose.yaml my_stack"은 .env의 변수를 대체하지 않습니다. 내가 무엇을 놓치고 있습니까? Docker 버전 18.09.0, 빌드 4d60db4입니다.

도커 스택 배포 -c <(docker-compose -f docker-compose-frpc-swarm-traefik.yml 구성) traefik

@kinghuang

/dev/fd/63 열기: 해당 파일이나 디렉토리가 없습니다.

경고: 일부 서비스(project1, project2)는 '배포' 키를 사용하며 무시됩니다. Compose는 '배포' 구성을 지원하지 않습니다 docker stack deploy 를 사용하여 떼에 배포하십시오.

@kinghuang
루트 환경만 오류를 보고하지 않습니다.

.envenv_file 지원이 배포/프로덕션 환경에서 항상 의미가 있는 것은 아닙니다. Docker Swarm의 다른 기능을 위해 파일 시스템에 직접 액세스할 필요가 없습니다. 따라서 해당 시스템의 책임 있는 설계자/운영자는 환경 파일을 파일 시스템에 덤프하는 기능을 제공하는 것을 원하지 않을 것입니다.

이론적으로 Swarm은 비밀을 환경에 자동으로 로드하는 것을 지원할 수 있지만 보안 면에서 좋은 생각이 아닐 수 있는 이유는 https://github.com/moby/moby/issues/30866#issuecomment -278924983을 참조하십시오.

오늘 할 수 있는 일은 비밀을 사용하고 컨테이너가 실행될 때 앱 환경에 로드하는 것입니다. 이를 통해 비밀 환경 값을 볼 수 있는 위치를 제어할 수 있습니다.

+1
도커 스택 배포는 실제로 --env-file을 지원해야 합니다.
나 자신은 동일한 .yml 파일을 재사용하여 개발/테스트/프로덕션 환경에 다른 스택을 배포하는 데 어려움을 겪고 있으며 스택을 배포하기 전에 환경 변수의 일부 성가신 내보내기/소싱을 처리하고 싶지 않습니다. 이것은 매우 오류가 발생하기 쉽습니다(그리고 매번 정확한 명령을 기억하는 데 어려움이 있습니다).
제 경우에는 환경별로 다른 인덱스 이름(elasticsearch)을 설정하고 싶지만 나머지 구성은 동일하게 유지됩니다. 이것은 이전 게시물에서 언급한 "비밀"과 관련이 없습니다.
위의 주석 기록을 기반으로 하여 docker 스택 배포를 위해 --env-file이 실제로 필요한 것으로 보이지만 안타깝게도 Docker 개발자는 그것을 보지 못하는 것 같습니다.

내 무리 환경에서 몇 가지 해결 방법을 결정했습니다.

  • 내가 설정 파일과 인증서를 로드하는 데 사용하는 secrets/configs.
  • 작성 파일을 제출하기 전에 실행하는 가변 보간 스크립트가 있는 Azure 개발 환경의 데모를 본 후 내 GitLab 릴리스 흐름에 넣은 내 자신을 작성했습니다.

docker-compose.yml에 .env 파일을 지정하기만 하면 작동합니다.

env_file:
  - .env

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

docker를 호출하기 전에 .env 파일을 구문 분석하기 위해 Windows에서 사용하는 powershell의 해결 방법:

switch -regex -file "./.env" { "^\s ([^#].+?)\s =\s (. )" { $name,$value = $matches[1..2]; 세트 항목 "env:$name" $value}}

.ini 파일 구문 분석에서 큰 영감을 얻었습니다. https://stackoverflow.com/questions/417798/ini-file-parsing-in-powershell

또 다른 해결 방법은 set -a && . .env && set +a && docker stack deploy... 입니다.

이건 말도 안돼. 나는 이것을 작동 시키려고 하루 종일 보냈습니다. docker stack 명령으로 .env를 읽지 않는다는 면책 조항이 문서 어딘가에 최소한 필요합니다.

@cjancsar 그렇습니다 . 문서 는 다음과 같이 말합니다.

중요: .env 파일 기능은 docker-compose up 명령을 사용할 때만 작동하며 docker stack deploy에서는 작동하지 않습니다.

관심이 없습니다. 사람들은 스웜 모드에서 현재 무엇을 하고 있으며 새로 빌드된 도커 이미지를 예를 들어 application:v1 에서 application:v2 , 동일한 서비스(다른 것은 변경되지 않음)로 업데이트하기를 원합니까?

이것이 내가 이 문제에 온 이유입니다. 그래서 관심이 있습니다.

현재 docker-compose에서 소스 제어 추적되지 않은 파일 . env 과 상호 작용하여 이미지 버전을 업데이트한 다음 docker-compose up -d 를 자동화하는 것은 간단합니다.

종종 커밋 sha를 '스테이징' 배포(충분한 테스트 주기 후 실제 릴리스에 사용되는 git 태그)를 위한 도커 이미지 버전으로 사용하므로 새 이미지 버전을 소스 제어에 커밋하는 것이 실제로 불가능합니다.

해결 방법으로 도커 비밀(실제로 비밀은 아니지만)을 업데이트할 수 있습니까? 그것이 사람들이 하는 일입니까, 아니면 다른 일들이 행해진 것입니까?

나는 이 문제의 미래 방문자를 요청하여 그들이 찾고 있는 기능이 (아직?) 존재하지 않기 때문에 현재의 모범 사례를 실제로 얻을 수 있도록 요청합니다.

안녕하세요, 저는 CI/CD 파이프라인에서 사용하기 위해 스택 배포를 조사하느라 바쁩니다. .env 파일을 사용할 수 있다는 것은 매우 유용할 것입니다. 이 옵션이 어떤 단계에서 도입될 것인지에 대한 피드백이 있습니까?

공식 권장 사항은 실제로 비밀 텍스트 파일에서 이러한 유형의 변수 읽기를 지원하도록 이미지 코드를 마이그레이션하는 것 같습니다. -- 스택/군집이 아닌 이전 버전과의 호환성을 위해 환경 변수에서도 읽을 수 있는 기능을 유지합니다.

이 예에서는 텍스트 파일당 하나의 비밀을 사용하므로 이전 .env 파일을 구문 분석할 필요가 없습니다.

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

한숨을 쉬다

이것은 문서에서 더 명확해야 합니다. @lengxuehxVariable Substitution 섹션에서 .env가 지원되지 않는다고 하지만 env_file 이 스택 배포에 대해 무시된다는 언급은 없습니다.

@kinghuang 이 제안한 솔루션이 작동하고 누군가가 말한 것처럼 배포 키를 제외 하지 않음 을 확인할 수 있습니다.

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

이것은 문서에서 더 명확해야 합니다. @lengxuehxVariable Substitution 섹션에서 .env가 지원되지 않는다고 하지만 env_file 이 스택 배포에 대해 무시된다는 언급은 없습니다.

docker compose가 하는 것처럼 env_file이 사용되었고 배포 스택 명령에 대해 작동하고 있음을 확인할 수 있습니다.

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

지금까지 이 글을 읽은 나와 같은 사람들을 위해 요약하자면:

  • docker stack deploy 는 "Variable Substitution"을 지원하지만 .env 파일에서 어떤 식으로든 환경 변수를 설정해야 합니다. 여러 옵션이 위에서 설명되었습니다. 가장 깔끔한 해결 방법 중 하나는 docker-compose config 를 전처리기로 사용하는 것입니다.
    따라서 docker stack deploy -c <(docker-compose config) STACK_NAME 로 스택을 생성할 수 있습니다.
  • Docker가 구성비밀 기능을 도입했지만 사용 사례가 있지만 "가변 대체"와 동일한 작업을 수행하지는 않습니다.
  • docker-compose.yml 파일의 env_file 매개변수는 docker-compose.yml 파일 자체가 아니라 생성된 컨테이너에 환경 변수를 설정하므로 " 변수 대체").

업데이트:

@thaJeztah님이 수정했습니다.

도커는 도커 스택 배포를 사용한 변수 대체를 지원하지 않으며 제안된 솔루션이 작동하지 않습니다.

docker stack deploy 는 변수 대체를 지원하지만 .env 파일을 평가하지 않습니다. 아래 예에서 HELLO_VERSIONlinux 로 설정되고 서비스는 기본 hello-world:latest 대신 hello-world:linux 태그를 사용합니다.

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

즉, docker-compose.yml 파일에서 env_file 매개변수를 사용하여 환경 변수를 계속 사용할 수 있습니다.

env_file 는 다른 용도로 사용됩니다( docker run --env-file 와 동일). env_file 옵션은 생성된 컨테이너에 설정할 환경 변수를 지정하지만 작성 파일 자체에서는 사용되지 않습니다(그리고 스택을 배포하기 전에 작성 파일에서 변수를 대체하는 데 사용되지 않음).

docker-compose와 docker 스택 사이의 다른 약간의 차이점과 함께 동일한 문제가 발생했습니다.
파이프로 이 문제를 처리하기 위해 https://github.com/egyel/dcsh script/tool을 만들었습니다.

image
안녕하세요 여러분, 이것은 env_file을 docker-compose에 넣는 데 도움이 되었습니다.

env_file: /path/to/env/file
~ 아니다

env_file:
  - /path/to/env/file

방금 다른 게시물에서 이것을 보았고 그것이 작동하는 이유(귀하의 추측과 동일)만 추측할 수 있지만 이것이 env_file이 작동하지 않는 문서에서 명시적으로 언급된 도커로 작동하는 이유에 대한 확인이 필요합니다.

내 이해는 env 파일이 자리 표시자를 채우는 데 사용할 수 없다는 것입니다.
docker-stack.yml 파일이지만 여전히 컨테이너에 제공할 수 있습니다.
당신이하고있는 일은 이미지 이름을 설정하는 것을 허용하지 않습니다.
예를 들어 env 파일.

2020년 5월 17일 일요일 06:08 raphy [email protected] 에서 다음과 같이 썼습니다.

[이미지: 이미지]
https://user-images.githubusercontent.com/30310576/82135555-a1e4be00-9836-11ea-9df4-a1b82e014b0e.png
안녕하세요 여러분, 이것은 env_file을 docker-compose에 넣는 데 도움이 되었습니다.

환경 파일: /경로/대상/환경/파일
~ 아니다

환경 파일:

  • /경로/대상/환경/파일

나는 방금 다른 게시물에서 이것을 보았고 그것이 작동하는 이유를 추측 할 수 있습니다.
(귀하의 추측과 동일) 그러나 이것이 왜 그런지에 대한 확인이 필요합니다.
env_file이하지 않는 docu에서 명시 적으로 언급 된 docker로 작동
일하다.


당신이 댓글을 달았기 때문에 이것을 받는 것입니다.
이 이메일에 직접 답장하고 GitHub에서 확인하세요.
https://github.com/moby/moby/issues/29133#issuecomment-629740002 또는
구독 취소
https://github.com/notifications/unsubscribe-auth/ABHLQMCARDQGJQIBWCQKAYLRR5PMHANCNFSM4CYRHCTA
.

위에서 언급한 docker-compose 솔루션:

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

.env 파일, 특히 docker-compose.override.yml 파일과 같은 것들이 일반적으로 개발 환경의 더 많은 부분을 차지한다는 단점이 있습니다. 프로덕션에 배포할 때 이러한 요소를 가져오는 것을 원하지 않습니다.

나는 약간의 중복을 포함하더라도 신중하게 일을 제어하는 ​​별도의 docker-compose-production.yml 를 갖게 되었습니다.

CLI가 .env 지원을 추가할 것이라고 생각하지 않습니다. docker stack deploy 명령은 원래 분산 응용 프로그램 번들 파일을 염두에 두고 빌드되었습니다(따라서 --bundle-file 옵션). DAB 파일은 docker-compose bundle 명령을 사용하여 Docker Compose에 의해 생성되었습니다. .env 및 기타 Compose 기능은 docker stack deploy 에 전달되기 전에 docker-compose 에 의해 처리됩니다. docker stack deploy 의 Compose 파일에 대한 직접 지원은 항상 타협이었습니다.

DAB 파일의 원래 약속은 이제 .env 도 처리하지 않는 Docker 앱에 있습니다.

개발자가 docker-compose config 를 사용하여 Docker Compose 프로젝트를 docker stack deploy 에 전달하기 전에 사전 처리하도록 했습니다. 다음을 사용하여 한 줄로 수행할 수 있습니다.

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

이렇게 하면 .env 처리를 포함한 모든 Docker Compose 기능이 완전히 적용됩니다.

이것은 매력처럼 작동합니다. 작성 파일에 "docker-compose.yml" 이름이 없으면 명령에 실제 작성 파일 이름이 포함되어야 합니다.

도커 스택 배포 -c <(docker-compose -f CUSTOM-COMPOSE-FILENAME.yml 구성) CUSTOM-STACK

<(docker-compose -f CUSTOM-COMPOSE-FILENAME.yml config 해킹 을 조심하세요!!! docker-compose configdocker-compose -f myfile.yml config 의 출력이 반드시 같지는 않습니다! 후자는 때때로 env 변수를 추가 따옴표로 묶기 때문에 출력이 잘못될 것입니다!

예시:

environment:
  SERVER_URL: '"xxx"'

대신에

environment:
  SERVER_URL: xxx

이 문제가 이미 어딘가에서 추적되고 있습니까?

이 페이지가 도움이 되었나요?
0 / 5 - 0 등급