通过 docker 入口点导出的环境变量在登录容器时不显示

Exported environmental variable via docker entrypoint are not shown when logging into the container

假设一个简单的 Dockerfile

FROM php-fpm:8
ADD entrypoint.sh .
RUN chmod +x entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
CMD ["php-fpm"]

在入口点脚本中,我只是导出一个变量并打印环境

#!/bin/bash

set -e

export FOO=bar
env // just print the environment while entry point is running

exec "$@"

然后我将映像构建为 myimage 并使用它以 docker 集群模式

部署堆栈
docker stack deploy -c docker-compose.yml teststack


// The docker-compose.yml file used is the following:

app:
  image: myimage:latest
  environment:
    APP_ENV: production

现在的问题是:如果检查 app 服务的日志,我可以看到(由于入口点中的 env 命令)导出了 FOO 变量

docker service logs teststack_app 

teststack_app.1.nbcqgnspn1te@soulatso    | PWD=/var/www/html
teststack_app.1.nbcqgnspn1te@soulatso    | FOO=bar
teststack_app.1.nbcqgnspn1te@soulatso    | HOME=/root

但是,如果我登录 运行ning 容器并手动 运行 env,则不会显示 FOO 变量

docker container exec -it teststack_app.1.nbcqgnspn1tebirfatqiogmwp bash

root@df9c6d9c5f98:/var/www/html# env // run env inside the container

PWD=/var/www/html
HOME=/root
// No FOO variable :(

我在这里缺少什么?

您通过 docker exec 启动的调试 shell 不是主容器进程的子进程,并且 运行 本身不是入口点,因此它不是查看在那里设置的环境变量。

根据您要执行的操作,有几种方法可以解决此问题。

如果您只是想检查镜像生成的内容,则可以启动调试容器。您在此处传递的命令将覆盖 Dockerfile 中的 CMD,当您的入口点脚本执行类似 exec "$@" 到 运行 的命令时,它将 运行 这命令代替。这使您可以在入口点的首次设置发生后立即检查环境中的事物。

docker-compose run app env | grep FOO
docker-compose run app bash

或者,如果您的入口点脚本只是设置环境变量,您可以显式调用它。

docker-compose exec app ./entrypoint.sh bash

入口点脚本接受普通命令作为参数很重要。如果它是 shell 脚本,它应该使用类似 exec "$@" 的东西启动主容器进程。如果您的入口点忽略其参数并启动固定命令,或者如果您将 ENTRYPOINT 设置为语言解释器并将 CMD 设置为脚本名称,这些调试技术将不起作用。