如何通过AWS SSM参数存储在运行时设置Docker容器环境变量
解决方案:启动时从AWS SSM动态拉取环境变量
核心思路
让容器在启动阶段执行一个前置脚本,从AWS SSM Parameter Store拉取最新的参数并注入环境变量,再启动应用。这样每次WatchTower重启容器时,都会重新拉取最新参数,完全符合你的需求。
步骤1:配置AWS权限(推荐用EC2实例角色)
为了避免手动管理AWS凭证,给运行Docker的EC2实例绑定一个IAM角色,赋予它读取SSM参数的权限:
- 创建IAM策略,允许访问指定路径的SSM参数:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["ssm:GetParametersByPath", "ssm:GetParameters"], "Resource": "arn:aws:ssm:<你的区域>:<你的账号ID>:parameter/<你的参数前缀>/*" } ] }
- 将该策略附加到EC2实例的IAM角色上,实例会自动获取临时凭证,无需手动传入
AWS_ACCESS_KEY_ID等环境变量。
如果必须用手动凭证,也可以在启动容器时通过-e传入,或者挂载宿主机的~/.aws/credentials文件到容器内。
步骤2:编写容器启动脚本
在容器内添加一个启动脚本,负责拉取SSM参数并启动应用。示例脚本start.sh:
#!/bin/bash set -e # 拉取SSM参数(替换成你的参数前缀) SSM_PATH="/myapp/" PARAMS=$(aws ssm get-parameters-by-path --path "$SSM_PATH" --recursive --with-decryption --output text --query "Parameters[*].{Name:Name,Value:Value}") # 将参数转换为环境变量(比如/myapp/DB_PASSWORD → DB_PASSWORD) echo "$PARAMS" | while read -r NAME VALUE; do ENV_VAR=$(echo "$NAME" | sed "s|^$SSM_PATH||" | tr '[:lower:]' '[:upper:]' | tr '/' '_') export "$ENV_VAR"="$VALUE" done # 启动你的应用(替换成实际启动命令) exec node app.js
步骤3:修改Dockerfile集成脚本
将启动脚本加入Docker镜像,确保安装AWS CLI(或用对应语言的AWS SDK替代,更轻量):
FROM node:18-alpine # 安装AWS CLI(Alpine环境) RUN apk add --no-cache aws-cli # 复制启动脚本并赋予执行权限 COPY start.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/start.sh # 复制应用代码 COPY app.js /app/ WORKDIR /app # 设置启动命令为脚本 CMD ["start.sh"]
步骤4:运行容器(验证)
如果用EC2实例角色,直接启动容器即可:
docker run -d --name myapp myapp-image
如果用手动凭证:
docker run -d --name myapp \ -e AWS_ACCESS_KEY_ID=<你的AK> \ -e AWS_SECRET_ACCESS_KEY=<你的SK> \ -e AWS_REGION=<你的区域> \ myapp-image
当WatchTower检测到新镜像重启容器时,启动脚本会自动拉取最新的SSM参数,无需额外配置。
其他可选方案
1. 使用专门的参数注入工具(ssm-env)
ssm-env是一个轻量工具,可以直接从SSM拉取参数并注入到命令的环境变量中,替代自定义脚本:
- 在Dockerfile中安装
ssm-env:
FROM node:18-alpine RUN wget -O /usr/local/bin/ssm-env https://github.com/remind101/ssm-env/releases/latest/download/ssm-env-linux-amd64 RUN chmod +x /usr/local/bin/ssm-env COPY app.js /app/ WORKDIR /app CMD ["ssm-env", "-prefix", "/myapp/", "node", "app.js"]
2. Docker Secrets(适用于Docker Swarm)
如果后续将EC2升级为Docker Swarm集群,可以用Docker Secrets同步AWS Secrets Manager的内容:
- 编写脚本定期将Secrets Manager的密钥同步到Swarm Secrets
- 容器挂载Secrets到指定路径,应用从文件读取密钥
3. 应用内直接拉取参数
如果你的应用支持,可以在应用启动时直接用AWS SDK读取SSM参数,无需启动脚本:
- 比如Node.js应用使用
aws-sdk-v3的SSM客户端,启动时拉取参数并加载到环境变量
内容的提问来源于stack exchange,提问作者PGT
相关产品推荐
相关产品推荐

