Docker Compose 似乎无法读取 env 文件中定义的 env 变量

hot*_*oup 6 docker docker-compose

我有以下项目目录结构:

myapp/
    docker/
        docker-compose.yml
    .env
    src/
        <my source code here>
    config.properties
Run Code Online (Sandbox Code Playgroud)

这是我的.env文件:

ENV=local
SERVICE_DB_HOST=0.0.0.0
SERVICE_DB_PORT=3306
SERVICE_DB_ROOT_PASSWORD=12345
SERVICE_DB_APP_USER=my-service-user
SERVICE_DB_APP_PASSWORD=23456
Run Code Online (Sandbox Code Playgroud)

这是我的docker/docker-compose.yml

version: "3.7"
services:
  myapp-main-db:
    env_file:
      - ../.env
    image: mysql:8
    container_name: myapp-main-db
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    ports:
      - $SERVICE_DB_PORT:$SERVICE_DB_PORT
    environment:
      MYSQL_ROOT_PASSWORD: $SERVICE_DB_ROOT_PASSWORD
      MYSQL_DATABASE: myapp_service_db_$ENV
      MYSQL_USER: $SERVICE_DB_APP_USER
      MYSQL_PASSWORD: $SERVICE_DB_APP_PASSWORD
    volumes:
      - myapp-service-db-data:/var/lib/mysql
volumes:
  myapp-service-db-data:
Run Code Online (Sandbox Code Playgroud)

当我docker-compose -f docker/docker-compose.yml up -d从项目根目录运行时,我看到 MySQL 容器毫无问题地启动,并通过docker ps.

但是,我无法使用预期的连接字符串和凭据连接到它,我确信这正确的。这让我相信 Docker Compose 没有../.env按照我的预期加载文件,因此中定义的任何变量都../.env不会作为环境变量注入。

有人能发现我哪里出了问题吗?

更新

当我跑步时docker-compose config我得到:

$ docker-compose config
WARNING: The SERVICE_DB_PORT variable is not set. Defaulting to a blank string.
WARNING: The SERVICE_DB_ROOT_PASSWORD variable is not set. Defaulting to a blank string.
WARNING: The ENV variable is not set. Defaulting to a blank string.
WARNING: The SERVICE_DB_APP_USER variable is not set. Defaulting to a blank string.
WARNING: The SERVICE_DB_APP_PASSWORD variable is not set. Defaulting to a blank string.
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.myapp-main-db.ports contains an invalid type, it should be a number, or an object
Run Code Online (Sandbox Code Playgroud)

Dav*_*aze 7

Compose 有两个独立的环境文件处理层:

  1. docker-compose.yml读入文件时,它会.env从与 相同的目录中读取文件docker-compose.yml,并使用该文件来扩展$VARIABLE引用。
  2. 当启动单个容器时,它会读取env_file:并使用它来设置容器中的环境变量。

由于.env与文件不在同一目录中docker-compose.yml,因此 Compose 在扩展文件中的变量之前不会读取它。这会导致容器获取数据库凭据的空字符串,并因为ports:格式错误而出现错误。

您可以移动.env到与docker-compose.yml

mv .env docker
docker-compose -f docker/docker-compose.yml up
Run Code Online (Sandbox Code Playgroud)

或传递一个docker-compose --env-file选项

docker-compose -f docker-docker-compose.yml --env-file .env up
Run Code Online (Sandbox Code Playgroud)

您不需要env_file:docker-compose.yml该文件中用于此特定用途,并且可以将其删除。


要进一步调试,您可以docker-compose run使用带有备用command:. 例如,您可以docker-compose run myapp-main-db env打印出其环境,而不是启动数据库。我希望您在这里看到的流程是:

  1. Compose 读取docker/.env(从与文件相同的目录docker-compose.yml),这是不存在的
  2. Compose 替换文件中的变量;我希望看到的MYSQL_USER是一个空字符串
  3. 撰写读取env_file:; 容器将具有SERVICE_DB_APP_USER=my-service-user该文件中的附加环境变量


小智 3

根据 docker 的默认行为,Dockerfile 和 docker-compose 永远不会从父目录读取任何文件或值。它总是从当前目录或子目录中读取。

因此,对于您的代码,我建议请使用 source/root 目录中的 docker-compose 文件。

例子:

myapp/
    docker-compose.yml
    .env
    src/
        <my source code here>
    config.properties
Run Code Online (Sandbox Code Playgroud)