Makefile中执行docker run传递AWS凭证环境变量报错如何解决
问题原因
这个问题的核心是Make执行目标下命令的环境传递逻辑和交互式终端直接执行命令不一致,具体触发逻辑:
- 你直接在终端执行docker命令时,当前交互式shell已经持有
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY两个环境变量的有效值,docker检测到-e参数后只写了变量名、没有显式赋值,就会自动从当前进程环境读取对应变量值注入容器,boto3优先读取环境变量中的凭证,所以可以正常运行。 - 执行
make run时,Make会为每一行命令启动独立的非交互式shell进程运行:- 非交互式shell默认不会加载交互式终端启动时读取的
~/.bashrc/~/.zshrc中的环境变量配置 - Make默认不会自动将外层shell中的普通环境变量透传到命令执行的子shell,除非显式声明导出
- 如果Makefile其他位置存在
AWS_ACCESS_KEY_ID =、AWS_SECRET_ACCESS_KEY =这类空赋值,Make会优先使用Makefile内的空值覆盖外层环境的有效值
最终docker进程拿不到两个环境变量的有效值,相当于给容器传入了空值凭证,boto3校验失败抛出错误。
- 非交互式shell默认不会加载交互式终端启动时读取的
修复方案
选择任意一种方案即可解决:
方案1:显式导出需要的AWS环境变量(最推荐,改动最小)
在Makefile中显式声明要导出对应环境变量,确保子shell可以拿到有效值:# 放在Makefile开头即可,对所有目标生效 export AWS_ACCESS_KEY_ID export AWS_SECRET_ACCESS_KEY # 如果用到临时会话、指定默认区域可以按需追加 # export AWS_SESSION_TOKEN # export AWS_DEFAULT_REGION run: docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY my_app_name注意:Makefile中命令行必须用Tab键缩进,不能用空格
方案2:直接挂载本地AWS配置目录(无需传环境变量)
你本地已经在~/.aws/路径下配置了完整的config和credentials文件,可以直接将这个目录挂载到容器内的AWS默认配置路径,boto3会自动读取文件中的凭证,无需传递环境变量:run: # 如果容器内以root用户运行用这个路径 docker run -v ~/.aws:/root/.aws my_app_name # 如果容器内是非root用户,替换为对应用户的home路径,比如/appuser用户就用-v ~/.aws:/home/appuser/.aws方案3:执行make命令时显式传参
不想改Makefile的话,执行make run时直接把变量值透传给Make即可:make run AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY方案4:开启Make的全量环境变量导出
在Makefile开头加特殊目标,让Make把所有能获取到的环境变量都透传到子shell:.EXPORT_ALL_VARIABLES: run: docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY my_app_name
内容的提问来源于stack exchange,提问作者jtlz2
相关产品推荐
相关产品推荐

