通过 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
设置为脚本名称,这些调试技术将不起作用。
假设一个简单的 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
设置为脚本名称,这些调试技术将不起作用。