Docker-compose env文件无法正常工作

imr*_*ani 7 external environment-variables docker-compose

我正在写docker-compose文件到MySQL实例,并想从env文件中使用一些变量:这里的文件实际上是这样的:

泊坞窗,compose.yml

version: '3.3'
services:
  db:
    image: mysql
    restart: always
    env_file:
      - ./imran.env
    environment:
      MYSQL_ROOT_PASSWORD: ${PASS}
    ports:
      - ${PORT1}: ${PORT2}
Run Code Online (Sandbox Code Playgroud)

imran.env

PASS=imran123
PORT1=3306
PORT2=3306
Run Code Online (Sandbox Code Playgroud)

而不是正确的工作我得到以下错误:

WARNING: The PASS variable is not set. Defaulting to a blank string.
WARNING: The PORT2 variable is not set. Defaulting to a blank string.
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.db.ports contains unsupported option: '${PORT1}
Run Code Online (Sandbox Code Playgroud)

请帮忙

Cod*_*jay 85

项目根目录中的 .env 文件和 Compose 文件中的 env_file: 字段是两个不同的概念。

.env 用于设置 Compose 的默认环境。在此文件中设置的值可以在 Compose 文件中使用。

env_file: 字段用于设置容器的默认环境。此处设置的值可以在容器中使用,但不能在 Compose 文件中使用。

请参阅https://docs.docker.com/compose/env-file/了解更多信息。

  • 天哪,谢谢你!Docker 官方文档在谈论“环境变量优先级”时列出了这两个选项,就好像它们实现了相同的目的,只是它们的优先级不同。但它们根本不能互换!https://docs.docker.com/compose/environment-variables/envvars-precedence/ (10认同)
  • 我想这应该是公认的答案。除此之外,我假设 `docker-compose --env-file` 选项实际上是用于设置 Compose 的默认环境 (3认同)
  • 这个答案就在这里,伙计们 (2认同)

Nic*_*lay 13

您的docker-compose.yaml文件中存在一些问题:

A:

space端口值之间的符号.应该没有空格:

ports:
  - ${PORT1}:${PORT2}
Run Code Online (Sandbox Code Playgroud)

B:

您需要在文件夹中使用.env文件,docker-compose.yaml以便为docker-compose.yaml文件和docker容器声明默认环境变量.env_filesection仅用于将值放入容器中.

所以,你应该做以下事情:

1.

使用ENV变量重命名文件.env:

mv imran.env .env
Run Code Online (Sandbox Code Playgroud)

2.

使用以下内容docker-compose.yaml后:

version: '3.3'
services:
  db:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${PASS}
    ports:
      - ${PORT1}:${PORT2}
Run Code Online (Sandbox Code Playgroud)

  • 投反对票。这不是正确的答案。问题是如何显式指定环境文件。 (25认同)
  • 关于 env_file 选项的真正答案怎么样,我可以在其中指定外部文件路径,但它不起作用? (17认同)
  • @imranahmedani可能礼貌地接受答案? (14认同)
  • > “env_file 部分仅用于将值放入容器中” / 这确实是一个失败。他们应该创建一个选项来为“.env”文件指定自定义名称(和目录)... (4认同)

Cha*_*aye 9

我最近必须指定我希望我的容器使用.env作为其环境文件,例如:

version: '2.4'

services:

  myapp:
    build:
      context: .
    container_name: myapp01xj1
    env_file:
      - .env
Run Code Online (Sandbox Code Playgroud)


Don*_*lon 8

在它后面env_file添加时,它似乎被忽略environment了。根据我的经验,docker-compose 似乎有许多这样的“愚蠢”错误。

docker-compose.yaml有一些与 env 文件无关的错误。我纠正了他们一点。

$ tre
.
??? broken
?   ??? imran.env
?   ??? docker-compose.yaml
??? works
    ??? docker-compose.yaml
    ??? imran.env

$ bat broken/*
??????????????????????????????????????????????????????
       ? File: broken/docker-compose.yaml
??????????????????????????????????????????????????????
   1   ? version: '3.3'
   2   ? services:
   3   ?   db:
   4   ?     image: mysql
   5   ?     restart: always
   6   ?     env_file:
   7   ?       - ./imran.env
   8   ?     environment:
   9   ?       MYSQL_ROOT_PASSWORD: ${PASS}
??????????????????????????????????????????????????????
??????????????????????????????????????????????????????
       ? File: broken/imran.env
??????????????????????????????????????????????????????
   1   ? PASS=imran123
   2   ? MYSQL_ROOT_PASSWORD=changeme
   3   ? PORT1=3306
   4   ? PORT2=3306
??????????????????????????????????????????????????????

$ diff broken works
diff broken/docker-compose.yaml works/docker-compose.yaml
8,9d7
<     environment:
<       MYSQL_ROOT_PASSWORD: ${PASS}
Run Code Online (Sandbox Code Playgroud)

随着environment,它失败:

$ cd broken && docker-compose down && docker-compose up -d
WARNING: The PASS variable is not set. Defaulting to a blank string.
Stopping broken_db_1 ... done
Removing broken_db_1 ... done
Removing network broken_default
WARNING: The PASS variable is not set. Defaulting to a blank string.
Creating network "broken_default" with the default driver
Creating broken_db_1 ... done
Run Code Online (Sandbox Code Playgroud)

但没有environment,它的工作原理:

$ cd works && docker-compose down && docker-compose up -d
Removing works_db_1 ... done
Removing network works_default
Creating network "works_default" with the default driver
Creating works_db_1 ... done

$ docker exec -i -t works_db_1 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=ac76b84ca072
TERM=xterm
PASS=imran123
MYSQL_ROOT_PASSWORD=changeme
PORT1=3306
PORT2=3306
GOSU_VERSION=1.12
MYSQL_MAJOR=8.0
MYSQL_VERSION=8.0.21-1debian10
HOME=/root
Run Code Online (Sandbox Code Playgroud)

笔记:

  • Docker-compose 显然不喜欢${PORT1}in ports:,您必须提供实际数字。(在这种情况下,我只是删除了它,因为端口与 env 文件无关)
  • 如果您不提供根通行证,MySQL 映像将崩溃。我添加了一个,以便容器可以运行足够长的时间来转储其 env 并确认正在设置变量。
  • 19.03.5在 macOS Catalina 上使用 Docker 版本10.15.4

  • 似乎来自https://docs.docker.com/compose/environment-variables/#the-env-file。当您在多个文件中设置相同的环境变量时,Compose 使用以下优先级来选择使用哪个值:Compose 文件、Shell 环境变量、环境文件、Dockerfile、变量未定义 (5认同)

Jeh*_*ser 8

就我而言,我是docker-compose up从项目内的子目录运行的(错误地)。因此,请确保该docker-compose.yml文件 和.env位于同一目录中,并且您正在docker-compose up这两个文件所在的同一目录中运行。


Muh*_*eed 7

@nickgryg 答案很好,但在这里我将解释我在使用 env 时遇到的情况。这将有助于其他人理解。

我也无法访问.my-project.envdocker-compose 文件中的一些变量。

.my-project.env

ROCKETTYPE=SIMPLE
RANGE=15
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml

   env_file:
      - .my-project.env
    environment:
      - SPACEX:${ROCKETTYPE}
   # It was importing RANGE env not SPACEX inside my container.
Run Code Online (Sandbox Code Playgroud)

当我运行时docker-compose up -d,只有RANGEenv 可在我的容器中访问。


然后我想出了两个解决方案:

第一:在 docker-compose 中 不使用.my-project.env文件,仅使用文件名。.env

第二:我没有更改我的环境文件名。仅传入.my-project.envdocker-compose 命令。

docker-compose --env-file .my-project.env  up -d 
Run Code Online (Sandbox Code Playgroud)

Docker-Compose 版本docker-compose version 1.25.0

阅读官方 docker 文档


小智 5

根据这个docker 手册,如果在文件中使用环境变量,docker-compose.yml例如:

web:
  image: "webapp:${TAG}"
Run Code Online (Sandbox Code Playgroud)

或者

environment:
  MYSQL_ROOT_PASSWORD: ${PASS}
Run Code Online (Sandbox Code Playgroud)

Docker 在默认文件中查找这些变量.env;因此,像这样更改默认env文件docker-compose up --env-file imran.env就可以了。


tnt*_*nkn 5

这个问题似乎已经存在了一段时间,但对于好奇的后人(比如我自己)来说,正确的答案(至少是你真正认为的)如下:

  1. 正如本次讨论中其他好人提到的,env_file的属性docker-compose.yml是为容器设置环境变量,而不是为 docker-compose 文件设置环境变量,并且类似于docker run --env-file;

  2. 默认情况下.env,docker compose文件中的环境变量是由同一文件夹中的文件设置的;

  3. 要更改此默认文件docker compose --env-file,请通过指定替代文件来启动服务.env

答案直接来自这里

另外,请注意,正如此处提到的,传递替代 dotenv 文件会覆盖默认的.env.