You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在docker-entrypoint.sh中动态设置环境变量?

问题

我有一个Go二进制程序,运行后会输出如下格式的环境变量导出语句:

export FOO="BAR"
export BAZ="QUX"

我编写了docker-entrypoint.sh脚本,通过eval执行这些输出语句来设置环境变量,脚本内容如下:

#!/bin/bash
set -e

ssm_available() {
  if [ -z "$SSM_BASE_PATH" ]; then
    return 1
  fi

  return 0
}

export_ssm_params_go() {
  set -x
  eval $(./ssm_get_parameter --path ${SSM_BASE_PATH})
  exec "$@"
}

main() {
  if ssm_available; then
    echo "Info: Loading SSM Parameters" >&2
    export_ssm_params_go "$@"
  fi

  echo "Info: Starting ..." >&2
  exec "$@"
}

main "$@"

Dockerfile末尾配置如下:

...
ENTRYPOINT [ "sh", "docker-entrypoint.sh" ]
CMD ["node", "server.js"]

脚本执行成功,日志显示变量已被导出:

Info: Loading SSM Parameters
+ ./ssm_get_parameter --path /p-stack-fs/env/production
+ eval export 'FOO="TEST"'
+ export 'FOO=TEST'
+ exec node server.js

实际程序可以正常使用这些动态设置的环境变量,但通过docker exec进入容器执行env命令时,却看不到这些变量,只有Dockerfile中用ENV定义的变量能正常显示,请问这是什么原因?

解答

核心原因:进程环境变量的独立性

  1. 动态变量仅存在于容器主进程的空间中
    你通过eval设置的环境变量,首先是在docker-entrypoint.sh所在的shell进程中生效;随后脚本执行exec node server.js,这个命令会直接替换当前的shell进程为node进程,node进程会完全继承shell进程的环境变量,所以你的应用程序能正常读取到这些变量。

  2. docker exec启动的是全新独立进程
    docker exec的本质是在容器内创建一个全新的进程(默认是shell),这个进程的环境变量来源于容器启动时的初始环境——也就是Dockerfile里ENV定义的变量、docker run命令通过-e传入的变量,不会继承容器主进程(node)后续动态添加的环境变量。这就是为什么你用docker exec查不到这些变量,但应用本身能正常使用它们的原因。

内容的提问来源于stack exchange,提问作者PGT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:36:20