首页 > 解决方案 > 无法使用 Docker 容器中的 ENV 变量在 docker-compose 文件中执行 HEALTHCHECKS

问题描述

我有一个带有数据库服务的 docker-compose 文件,该文件获取用户和密码的环境文件(我删除了密码的 env 变量,因为用户和密码的问题相同):

db:
    restart: always
    container_name: db
    image: mariadb:10.3.9
    env_file:
      - my_env_file.env
    volumes:
      - /opt/dbdata:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysql", "-u", "${DB_USER}", "-e", "\"SHOW DATABASES;\""]
      interval: 1m
      timeout: 10s
      retries: 10

环境文件有一个 DB_USER 条目:

DB_USER=TEST

使用 docker-compose 构建和启动容器时,Docker 无法解析环境变量,因为该变量仅存在于db容器中,并且我收到以下警告:

WARNING: The DB_USER variable is not set. Defaulting to a blank string.

有没有办法告诉 Docker 避免在主机上解析这个 env 变量的值,而是从我的容器中解析它?

出于安全原因,我不想在主机上提供环境变量。

我也不想使用mysqladmin它,因为它可能导致误报(例如,健康检查可能会失败,因为数据库尚未接受连接)。

标签: dockerdocker-composeenvironment-variables

解决方案


docker-compose 将在 docker-compose 环境(运行 docker-compose 命令的地方)中扩展环境变量,而不是在容器环境中。您传递的环境变量仅在容器内设置(撰写文件已被解析,并且撰写文件中的变量已在加载环境变量文件时展开)。

在容器内部,需要一个 shell 来扩展环境变量(这$是一种 shell 语法,Linux 内核不进行这种扩展),但是您需要转义这些变量,以便 docker-compose 不会尝试扩展它们首先,你需要一个外壳。在 docker 容器中运行命令的 json 列表语法通过直接的 OS exec 系统调用运行,绕过 shell,因此您需要显式地将 shell 添加到 exec 语法,或者只使用 shell 语法。执行后者,将$值转义为$$

test: ["CMD-SHELL", "mysql -u $${DB_USER} -e \"SHOW DATABASES;\""]

有关更多详细信息,请参阅:


推荐阅读