Moby: `docker stack deploy` в версии 1.13 не загружает файл `.env`, как это делает `docker-compose up`

Созданный на 5 дек. 2016  ·  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 службы nginx и php я использовал ${DOCKER_USER} для получения идентификатора докера из переменных среды. И если я использую 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 правильное.

Я протестировал эту функцию на дроплете Digtial Ocean, который установил докер 1.13.0-rc2 через docker-machine .

Вот версия:

$ 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, мы использовали ее во многих наших файлах компоновки. Он разделяет динамические части и статические части файла docker-compose.yml . С загрузкой .env по умолчанию мы можем просто предоставить разные файлы .env для разных сред и сохранить docker-compose.yml и связанные скрипты статичными.

Невозможно использовать env_file или environment в docker-compose.yml для достижения того же результата замены envvars. .env — самый простой способ сделать это.

В противном случае нам придется ставить префикс export в каждой строке файла .env и вручную source .env каждый раз перед загрузкой docker-compose.yml , а иногда возможны дополнительные шаги. ошибиться.

Я только что заметил это.
Я предполагал/ожидал, что это будет работать так же, как и для 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

Я получаю сообщение об ошибке: Игнорирование неподдерживаемых параметров: сборка. Означает ли это, что он не будет создавать сборку из файла Dockerfile?

А также такая же ошибка для network_mode: игнорирование неподдерживаемых параметров: network_mode.

Ниже приведена команда:
DOCKER_IMAGE=akhil123 развертывание стека докеров -c docker-compose.yml foo

Спасибо заранее.

@akhildangore , пожалуйста, не комментируйте проблемы с вопросами, которые не имеют прямого отношения. Функция docker stack deploy _by design_ не выполняет сборки. Причина этого в том, что _build_ выполняется на хосте, с которого запускается команда, поэтому образ будет доступен только на _этом_ узле. При развертывании этого образа в 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 будет включена в выпуск 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, которую служба должна прослушивать, и т. д.

Я могу набросать PR, который загрузит файл .env , если он существует в том же каталоге, что и docker-compose.yml , если мы считаем, что приведенные выше варианты использования имеют смысл.

Дизайн команды docker stack deploy немного отличается от команды docker-compose . Я не думаю, что имеет смысл просто читать .env по умолчанию. Даже docker-compse.yml не читается по умолчанию, потому что в будущем источником развертывания по умолчанию, вероятно, будет что-то другое.

Вы всегда можете получить файл .env самостоятельно перед запуском stack deploy .

Просто . .env перед вызовом docker stack deploy не помогает, $переменные не подставляются. Помог только трюк с env .. xargs .
Было бы неплохо иметь опцию --env-file=FILE как в docker run .

Просто . .env перед вызовом развертывания стека докеров не помогает

Это должно помочь @C-Pro - вам нужно иметь строки export ... в вашем файле .env . В качестве альтернативы вы можете сделать 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 предоставляется в контейнере, но не предоставляется на хост-компьютере.
Это означает, что я могу использовать файл .env вместо раздела environment , но я не могу использовать файл .env с подстановкой переменных.
Версия докера: v17.03

@ddpaimon
окружающая обстановка:
- FOO=${BAR}

Похоже, что этот файл .env работает только для контейнера, но не для замены переменной файла docker-compose.yml.

Docker для MAC, версия Docker 17.03.1-ce, сборка c6d412e

@realcbb
да. Но для использования файловых переменных .env внутри контейнера вы должны удалить их в разделе environment .
Например:
докер-compose.yml

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

.env

FOO=filled

В контейнере я получил это:

$ env
FOO=empty

Но если я удалю FOO из раздела environment в docker-compose.yml , я получу следующее:

$ env
FOO=filled

@ddpaimon
Переменные среды, указанные в среде, переопределяют эти значения, указанные в файле .env.

@dnephin : вы заявляете, что .env не является частью формата файла компоновки докеров. Однако функция файла .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 , например compose.

Мой вариант использования заключается в том, что я использую docker stack deploy в средах разработки, тестирования, подготовки и использую переменные среды для параметров стека, чтобы сохранить файл yml одинаковым.

В настоящее время используется один из обходных путей, опубликованных здесь, но предпочтительным путем будет использование файла .env .

Просто дружеское напоминание: возможно, вы пытаетесь использовать файлы dotenv для хранения ключей API, паролей и других вещей, которые считаются «чувствительными» для помещения в кластер. В этих случаях вы должны использовать Docker Secrets .

Что касается других вещей, могу ли я предложить иметь один файл компоновки для каждой развернутой/развертываемой среды? Большая часть вещей, которые меняются между разными средами, будут доступными серверами, различной организацией серверов и т. д. и, следовательно, потребуются разные значения содержимого deploy deploy (правила placement , resources резервирование

На самом деле мне нужна эта функция, переменные в файле компоновки можно рассматривать как разные значения на разных хостах при использовании развертывания стека докеров.

«Что касается других вещей, могу ли я предложить иметь один файл компоновки для каждой развернутой/развертываемой среды? Большинство вещей, которые меняются между разными средами, будут доступными серверами, другой организацией серверов и т. д. и, следовательно, потребуются разные значения в ключе развертывания. содержание (правила размещения, резервирование ресурсов и т. д.), что делает использование одного файла для всего слишком сложным».

@vovimayhem Извините за прямоту, но это не имеет такого большого смысла, как использование одного файла компоновки с заменой переменных с использованием env_file. Я бы предпочел использовать формат env_file, так как это также значительно облегчает мне предоставление стеков в качестве результата для моих клиентов и обучение их обновлению одного файла vars в стиле ini, чем возиться с файлом компоновки (который я НЕ ДОПУСКАЮ). «Хочу»).

Конфигурации службы — отличное дополнение, но они не кажутся пригодными для интерполяции времени развертывания (например, $TAG).

Если переменные среды вообще поддерживаются, то будьте последовательны в механизмах, используемых для их разрешения в разных инструментах. Развертывание стека кажется непоследовательным, без фундаментального изменения поведения переменных среды. Секреты и сервисные конфигурации являются лучшей альтернативой некоторым вариантам использования переменных среды, но они не включают в себя.

Ты, кажется, не понимаешь @vovimayhem. Я не говорю о передаче env в контейнеры; это работает так, как ожидалось. Я имею в виду использование env_file, который анализируется во время stack deploy , как это было во время compose up .

@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 . Имхо, это регресс. Кроме того, в вашем примере вы все еще передаете переменную среды в контейнер. Я могу сделать это сегодня с env_files ; проблема заключается в разборе env_file во время операции stack deploy -c docker-compose.yml .

Это особенно болезненно, поскольку stack больше не поддерживает несколько файлов компоновки, иначе можно было бы просто использовать дополнительный файл компоновки для каждой среды. Чтобы сделать это таким образом, требуется создать файл стека из файлов компоновки, что представляет собой еще один шаг. Так что, как ни крути, мы перешли от одноэтапного процесса к многоэтапному, чтобы достичь одного и того же конечного результата.

Кроме того, FWIW, configs , по моему опыту, действительно не соответствует реальным конфигурациям. Я предполагал (надеялся), что у меня может быть /application/config.conf в исходном коде. Обновите этот файл, зафиксируйте, нажмите, и CI повторно развернет стек с новой конфигурацией. Это невозможно без какого-либо хакерства, чтобы изменить имя файла или какой-либо другой механизм. Конечно, мы можем как минимум проверить контрольную сумму файла или сканировать изменения содержимого и обновлять его на основе самого файла? В общем, кажется, что мы идем назад. Добавьте поддержку K8s сейчас, и это заставляет меня задаться вопросом, будет ли рой просто чахнуть на лозе, пока он не потеряет достаточно использования, чтобы его тихо отбросили.

Кроме того, 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, удаления предупреждений из вывода, а затем направляет его в развертывание стека докеров через стандартный ввод.
Замените '-f stack.yml' именем вашего файла конфигурации или опустите его, чтобы использовать docker-compose.yml по умолчанию.

+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 .

Прошел год, а нам все еще нужно взломать это, чтобы оно заработало. Начиная с 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

Я возился с этим в течение многих часов и, похоже, выполняю некоторую фоновую работу со сценарием (для этого я буду использовать CI), чтобы создать файл DAB из этих различных частей. Было бы неплохо иметь инструмент для докеров, который делал бы это... :-) Может быть, добавить --env-file version.env к docker-compose bundle ?

В моем случае использования я хочу использовать «манифест» version.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 менеджеру и выполнил docker deploy .

Это рабочий процесс, который Докер имел в виду @thaJeztah? Есть ли способ лучше?

[править] Это не работает, так как DAB игнорирует директивы volume: , network: и deploy: . Я просто загружаю файл env в оболочку, перестраиваю временный файл компоновки, а затем развертываю его.

Мне бы хотелось, чтобы файлы .env читались по умолчанию, как в Docker Compose, а --env-file (короткий -e ) добавлялся бы для docker stack deploy , чтобы иметь возможность переопределять переменные среды и значения по умолчанию из файла .env .

+1
Было бы довольно удобно читать .env в первую очередь, как это делает docker-compose.
Либо по умолчанию, либо просто передайте файл env в качестве параметра в командной строке стека докеров.

Два уже упомянутых обходных пути (найдите их также ниже) работают, хотя и немного некрасиво по сравнению с предложенным «исправлением».

_echo "$(docker-compose -f stack.yml config 2>/dev/null)" | развертывание стека докеров -c-имя_стека_

_env $(cat .env | grep ^[AZ] | xargs) развертывание стека докеров --compose-file docker-compose.yml [STACK_NAME]_

Я бы добавил, что установка docker-compose только для обработки этих переменных также может быть довольно опасной.

Если кто-то по ошибке развернет стек, используя docker-compose up -d вместо использования docker stack deploy, это, скорее всего, вызовет ошибки приложений и повреждение файлов.

Интерполяция переменных среды при развертывании — лучшее решение для непрерывной интеграции.

Одна из проблем с использованием «.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

И это работало нормально, но мне нужно было добавить 3 МБ или около того к моему контейнеру.

Хороший @rnickle , но все еще «хакерский» по сравнению с Docker, который может делать это так, как раньше. Кажется (и, пожалуйста, чуваки из Docker, поправьте меня, если я ошибаюсь), что с момента объявления о поддержке K8s очень мало усилий вкладывается в режим роя, поэтому я сомневаюсь, что какие-либо из этих регрессий будут устранены.

И это работало нормально, но мне нужно было добавить 3 МБ или около того к моему контейнеру.

Если переменные окружения установлены, docker slack deploy уже должны их интерполировать.

по сравнению с Docker, который может делать это так, как раньше.

В Docker никогда не было этой функции; докер составил; docker compose и docker stack deploy совместно используют _формат файла_, но не обязательно все поведения самого программного обеспечения.

что с момента объявления о поддержке K8s очень мало усилий для перехода в режим роя

Обработка файлов Compose выполняется на стороне клиента и используется как для k8s, так и для swarmkit, так что в этой области ничего не замедляется, кроме того, что «мы можем сделать так много в любой момент времени».

Для тех, кто ждет эту функцию; в предстоящем выпуске будет поддержка нескольких файлов компоновки для docker stack deploy , поэтому, если вы в настоящее время используете эту функцию в компоновке докеров: предстоящий выпуск докеров также будет поддерживать это

Семантика в сторону, спасибо за обновление. Когда я говорю Docker, я имею в виду не обязательно демон или движок, а компанию, которая создает инструменты. Возникновение комментария о том, что усилий мало, на самом деле связано с тем фактом, что swarm-mode отсутствует уже более года и все еще НАМНОГО отстает от того, что было с одним узлом, использующим compose.

Я могу понять, что они разные, но используют один и тот же формат файла, но на самом деле это приводит к большей путанице и потенциально разочаровывает, когда пользователи обнаруживают, что им приходится обменивать функции на использование swarm. Это и тот факт, что файлы DAB ВСЕ ЕЩЕ указаны как экспериментальные. К сожалению, мы приняли решение использовать swarm-mode в большом проекте, иначе мне было бы все равно. К счастью, мы больше не совершим эту ошибку.

[редактировать]

Если переменные среды установлены, docker slack deploy уже должен интерполировать их.

Делать это в среде CI — адская головная боль. По сути, я закончил тем, что установил compose, взял envvars, промыл файл compose (после извлечения изображений), а затем выплюнул новый файл compose для использования с stack deploy . (И я даже не буду рассказывать о том, как это больно, когда :latest не означает :latest в режиме роя, поскольку эта проблема касается именно интерполяции переменных.)

_EDIT: я надеюсь, что этот пост не будет выглядеть агрессивно. Мне нравится концепция Docker Stack, и я думаю, что весь пакет Docker довольно хорошо поддерживается. Просто кажется, что Docker (организация) в настоящее время не рассматривает свои продукты так же, как пользователи, что досадно и, по-видимому, является причиной большинства проблем, с которыми я сталкивался при использовании Compose и Stack._

В Docker никогда не было этой функции; докер составил; docker compose и docker stack deploy имеют общий формат файла, но не обязательно все поведение самого программного обеспечения.

Я чувствую, что это заявление раскрывает фундаментальное несоответствие между тем, как разработчики Docker и пользователи рассматривают эти продукты. Как пользователь, независимо от того, работаю ли я с Docker Engine, Docker Compose или Docker Swarm, это все Docker, и он должен вести себя последовательно, насколько это возможно.

Мое понимание цели этих продуктов:

  • Docker Engine предназначен для создания и запуска отдельных контейнеров.
  • Docker Compose предназначен для запуска набора контейнеров в разработке.
  • Docker Stack предназначен для развертывания контейнеров в рабочей среде.

Одним из ключевых преимуществ Docker (и контейнеров в целом) является простота повторного использования одного и того же приложения в нескольких средах. Следовательно, Compose должен быть добавлен к Engine, а Stack должен быть добавлен к Compose. В частности, поскольку они используют один и тот же формат файла, Stack, не поддерживающий функции Compose, приводит к путанице для разработчиков и усложняет процессы CI.

Я бы не сказал, что композиция предназначена для разработки, а стек — для разработки. Я рассматриваю композицию как многоконтейнерное приложение или «систему», а стек — для многоузловых развертываний с использованием режима роя в качестве планировщика/оркестратора. В остальном ваш комментарий верен на 100%. Я также разочарован (если это не было очевидно из моих других комментариев), что существует разрыв между разработчиками и пользователями в отношении того, как используются продукты.

Ух ты. Я присоединился к путанице и боли, когда оценивал Docker Swarm для большого проекта.
Все секреты — это развлечение и игра, просто не все внешние образы докеров поддерживают чтение секретов из файлов. Я не хочу модифицировать для каждого из них и размещать собственное изображение. Да, я могу использовать их для своих проектов, но для внешних проектов не годится.
Так что остаются переменные env. Но эй, они ведут себя по-разному от составления до стека! Каково же было мое удивление, когда я заметил, что они на самом деле не работают.
Как возможно иметь стек докеров без поддержки env? Лучше всего, на мой взгляд, --env-file=dev.env , чтобы он не мешал другим файлам env... но поддержка этого ужасна. К сожалению, я должен вернуться к k8s, так как стек, отсутствующий с самого начала, может оказаться ужасным выбором во время производства, кто знает, сколько других вещей будет отсутствовать.

Прошло два года, а мы до сих пор такие... Не хочу показаться грубым, но давайте! Это вопрос повторного использования части кода из docker-compose!

Еще одна похожая проблема, с которой я только что столкнулся, заключается в том, что даже если вы используете env_file, поведение все равно не совсем то же самое.

Я использую env_file для загрузки путей, указанных из корня проекта, но мой файл компоновки находится в другом подкаталоге. Чтобы запустить с помощью docker-compose, я просто использую --project-directory. -f путь/к/docker-compose.yml

docker stack не позволяет мне указать каталог проекта, из-за чего все мои env_files не загружаются.

Изменение env_file на «../../path/to/envrc» не работает с docker-compose, так как эти файлы должны находиться внутри корневого каталога проекта.

+1

+1

+1 это было бы действительно полезно. Не вижу минуса на самом деле.

Невероятно глупо, что докер еще не поддерживает это.

+1 @joao-fidalgo Это определенно так.

+1

Просто столкнулся с тем же, что и мы, когда пытаемся использовать рой. Я прочитал все сообщения в разных темах и остался крайне разочарован. ИМО, некоторые действительно хорошие моменты и сильные аргументы были сделаны @ntwrkguru и другими. Я надеюсь, что мы сможем рассмотреть возможность включения этой функции; взломы не помогут.

.env-файл

export MYSQL_USER=user

source .env && docker stack deploy

Он также будет работать с docker-compose up для bash.

.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 с помощью команды docker-compose bundle . .env и другие функции Compose будут обрабатываться docker-compose , прежде чем будут переданы docker stack deploy . Прямая поддержка файлов Compose в docker stack deploy всегда была скорее компромиссом.

Первоначальное обещание файлов DAB теперь живет в приложении Docker, которое также не обрабатывает .env .

Мои разработчики используют docker-compose config для предварительной обработки проектов Docker Compose перед передачей их в docker stack deploy . Вы можете сделать это в одной строке с помощью:

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

Таким образом, все функции Docker Compose, включая обработку .env , будут полностью применены.

@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.

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

@кингхуанг

открыть /dev/fd/63: нет такого файла или каталога

ПРЕДУПРЕЖДЕНИЕ. Некоторые службы (проект1, проект2) используют ключ «развернуть», который будет проигнорирован. Compose не поддерживает конфигурацию «развертывание» — используйте docker stack deploy для развертывания в рой.

@кингхуанг
Только корневая среда не сообщит об ошибке.

Поддержка .env и env_file не всегда имеет смысл в среде развертывания/производства. Вам не нужен прямой доступ к файловой системе для любых других функций Docker Swarm. Таким образом, ответственный разработчик/оператор этой системы не хотел бы давать вам возможность выгружать файлы окружения в файловую систему.

Теоретически Swarm может поддерживать автоматическую загрузку секретов в среду, но см. https://github.com/moby/moby/issues/30866#issuecomment -278924983, почему это может быть плохой идеей с точки зрения безопасности.

Сегодня вы можете использовать секреты и загружать их в среду вашего приложения при запуске контейнера. Это дает вам контроль над тем, где можно увидеть значения секретной среды.

+1
Развертывание стека докеров действительно должно поддерживать --env-file.
Сам я борюсь с повторным использованием одного и того же файла .yml для развертывания разных стеков для сред разработки/тестирования/производства, и я не хочу иметь дело с каким-то неудобным экспортом/источником переменных среды до развертывания стека. Это очень подвержено ошибкам (и боль в заднице тоже каждый раз запоминать точные команды).
В моем конкретном случае я, например, хочу установить разные имена индексов (elasticsearch) для каждой среды, но остальная часть конфигурации остается прежней. Это не имеет ничего общего с «секретами», как упоминалось в предыдущих постах.
Кажется, существует реальная потребность в --env-file для развертывания стека докеров, основываясь на истории комментариев выше, но, к сожалению, разработчики Docker, похоже, этого не видят.

В моей среде роя я остановился на нескольких обходных путях:

  • secrets/configs, которые я использую для загрузки файлов конфигурации и сертификатов.
  • После просмотра демонстрации среды разработки Azure, где у них был сценарий интерполяции переменных, который они запускали перед отправкой файла компоновки, я написал свой собственный, который я включил в свой поток выпуска GitLab.

Просто укажите файл .env в вашем docker-compose.yml и все заработает:

env_file:
  - .env

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

Обходной путь в powershell для использования в Windows для анализа файла .env перед вызовом докера:

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

Вдохновленный разбором файлов .ini: https://stackoverflow.com/questions/417798/ini-file-parsing-in-powershell

Другой обходной путь: set -a && . .env && set +a && docker stack deploy... .

Это смешно. Я просто потратил весь день, пытаясь заставить это работать. По крайней мере, где-то в документах требуется отказ от ответственности, что .env не читается командами docker stack .

@cjancsar Да . В документации говорится:

Важно: функция файла .env работает только при использовании команды docker-compose up и не работает с развертыванием стека docker.

Из интереса. Что люди делают в настоящее время, когда находятся в режиме роя, и они хотят обновить свой недавно созданный образ докера, например, с приложения: v1 до приложения: 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

вздох

Это должно быть более ясно в документации. Хотя указано, что .env не поддерживается в разделе « Замена переменных » для @lengxuehx , не упоминается, что env_file игнорируется при развертывании стека.

Я могу подтвердить, что решение, предложенное @kinghuang , работает и не исключает ключ развертывания, как кто-то сказал.

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

Это должно быть более ясно в документации. Хотя указано, что .env не поддерживается в разделе « Подстановка переменных » для @lengxuehx , не упоминается, что env_file игнорируется при развертывании стека.

Я могу подтвердить, что env_file используется и работает для команды развертывания стека, точно так же, как это делает 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

Подводя итог, для таких людей, как я, которые прочитали это до сих пор:

  • docker stack deploy поддерживает «подстановку переменных», но вам нужно каким-то образом установить переменные среды из файла .env . Несколько вариантов были описаны выше. Одним из лучших обходных путей является использование docker-compose config в качестве препроцессора.
    Таким образом, вы можете создать свой стек с помощью docker stack deploy -c <(docker-compose config) STACK_NAME .
  • Хотя Docker представил возможности конфигураций и секретов , у них есть свои варианты использования, но они не будут делать то же самое, что «Замена переменных».
  • Параметр env_file в файле docker-compose.yml установит переменные среды в созданном контейнере, а не в самом файле docker-compose.yml (поэтому его нельзя использовать в качестве альтернативы " Замена переменной").

Обновлять:

Меня поправил @thaJeztah.

Docker не поддерживает замену переменных с помощью развертывания стека докеров, и ни одно из предложенных решений не работает.

docker stack deploy поддерживает подстановку переменных, но не оценивает файл .env ; в приведенном ниже примере для HELLO_VERSION установлено значение linux , и служба будет использовать тег hello-world:linux (вместо тега по умолчанию 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

При этом вы по-прежнему можете использовать переменные среды, используя параметр env_file в файле docker-compose.yml.

env_file служит другой цели (и является эквивалентом docker run --env-file ); опция env_file указывает, какие env-vars установить для созданного контейнера, но не используется в самом файле компоновки (и не используется для замены переменных в файле компоновки перед развертыванием стека).

У меня была такая же проблема с другими небольшими различиями между docker-compose и docker stack.
В итоге я создал 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, например.

Вс, 17 мая 2020 г., 06:08 [email protected] написал:

[изображение: изображение]
https://user-images.githubusercontent.com/30310576/82135555-a1e4be00-9836-11ea-9df4-a1b82e014b0e.png
Привет всем, это помогло мне поместить env_file в мой docker-compose:

env_file: /путь/к/env/файлу
нет

env_file:

  • /путь/к/env/файлу

я только что видел это из другого поста, и я могу только догадываться, почему это работает
(то же, что и ваше предположение), но нам нужно подтверждение того, почему это
работает как докер, явно упомянутый в документе, что env_file не
Работа.


Вы получаете это, потому что вы прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/29133#issuecomment-629740002 или
отписаться
https://github.com/notifications/unsubscribe-auth/ABHLQMCARDQGJQIBWCQKAYLRR5PMHANCNFSM4CYRHCTA
.

Упомянутое выше решение для создания докеров:

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 с помощью команды docker-compose bundle . .env и другие функции Compose будут обрабатываться docker-compose , прежде чем будут переданы docker stack deploy . Прямая поддержка файлов Compose в docker stack deploy всегда была скорее компромиссом.

Первоначальное обещание файлов DAB теперь живет в приложении Docker, которое также не обрабатывает .env .

Мои разработчики используют docker-compose config для предварительной обработки проектов Docker Compose перед передачей их в docker stack deploy . Вы можете сделать это в одной строке с помощью:

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

Таким образом, все функции Docker Compose, включая обработку .env , будут полностью применены.

Это работает как шарм, имейте в виду, что если ваш файл компоновки не имеет имени «docker-compose.yml», ваша команда должна включать фактическое имя файла компоновки.

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

ОСТЕРЕГАЙТЕСЬ ВЗЛОМА <(docker-compose -f CUSTOM-COMPOSE-FILENAME.yml config !!! Вывод docker-compose config и docker-compose -f myfile.yml config НЕ обязательно одинаков! Последний иногда заключает переменные env в дополнительные кавычки, поэтому вывод будет неверным!

Пример:

environment:
  SERVER_URL: '"xxx"'

вместо

environment:
  SERVER_URL: xxx

Эта проблема уже где-то отслеживается?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги