无法从GitHub Actions传递环境变量至Docker容器的问题排查
问题描述
我尝试通过GitHub Actions将变量传递到VPS上的Docker容器,工作流步骤如下:
- name: SSH into VPS and deploy uses: appleboy/ssh-action@master with: host: ${{ secrets.VPSHOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.SSH_KEY }} script: | export BLOG_POSTGRES_DB=${{ env.BLOG_POSTGRES_DB }} export BLOG_POSTGRES_USER=${{ env.BLOG_POSTGRES_USER }} export BLOG_POSTGRES_PASSWORD="${{ secrets.BLOG_POSTGRES_PASSWORD }}" export DJANGO_ALLOWED_HOSTS=${{ env.DJANGO_ALLOWED_HOSTS }} export DJANGO_SECRET_KEY="${{ secrets.DJANGO_SECRET_KEY }}" cd /home/username/blog docker-compose -f prod.yml build docker-compose -f prod.yml up -d
对应的docker-compose配置:
blog: # 其他配置省略 environment: DB_NAME: ${BLOG_POSTGRES_DB} DB_USER: ${BLOG_POSTGRES_USER} DB_PASSWORD: ${BLOG_POSTGRES_PASSWORD} DJANGO_SETTINGS_MODULE: blog_eng.config.settings.prod DB_HOST: some_host DB_PORT: 5432 DJANGO_ALLOWED_HOSTS: ${DJANGO_ALLOWED_HOSTS} DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY}
目前遇到的问题:通过GitHub Secrets设置的变量能正常传递到容器,但通过GitHub Variables设置的变量无法传递。我试过用env上下文访问,也直接用$VARIABLE的形式,都没有效果。需要让Variables里的变量和Secrets一样正常传递到容器中,求问题原因和解决办法。
可能的问题与解决思路
1. 核心错误:GitHub Variables的访问上下文用错了
GitHub仓库/组织级的变量(Variables)不是通过env上下文访问的,而是用vars上下文!你之前写的${{ env.BLOG_POSTGRES_DB }}是错误的,正确写法是${{ vars.BLOG_POSTGRES_DB }},所有Variables变量都要改成这个格式。
修正后的脚本片段:
export BLOG_POSTGRES_DB=${{ vars.BLOG_POSTGRES_DB }} export BLOG_POSTGRES_USER=${{ vars.BLOG_POSTGRES_USER }} export DJANGO_ALLOWED_HOSTS="${{ vars.DJANGO_ALLOWED_HOSTS }}"
2. 先验证变量是否传递到SSH会话
在SSH脚本里加调试命令,确认变量是否已经被GitHub正确注入到shell环境中:
# 在export之后、docker-compose之前添加 echo "BLOG_POSTGRES_DB value: $BLOG_POSTGRES_DB" printenv | grep -E "(BLOG_|DJANGO_ALLOWED_HOSTS)"
如果输出为空,说明GitHub没把变量传过来,要检查变量的作用域:
- 仓库级变量:必须在当前工作流所属的仓库设置
- 组织级变量:要确保已经勾选允许该仓库访问此变量
3. 处理变量中的特殊字符
如果Variables里的变量包含逗号、空格等特殊字符(比如DJANGO_ALLOWED_HOSTS是example.com,www.example.com),export时一定要用双引号包裹,避免被shell拆分:
export DJANGO_ALLOWED_HOSTS="${{ vars.DJANGO_ALLOWED_HOSTS }}"
4. 用env-file替代shell环境变量(更可靠的方案)
避免shell环境变量传递的不确定性,直接生成一个.env文件给docker-compose使用:
# 生成临时env文件 cat > .env.prod << EOF BLOG_POSTGRES_DB=${{ vars.BLOG_POSTGRES_DB }} BLOG_POSTGRES_USER=${{ vars.BLOG_POSTGRES_USER }} BLOG_POSTGRES_PASSWORD="${{ secrets.BLOG_POSTGRES_PASSWORD }}" DJANGO_ALLOWED_HOSTS="${{ vars.DJANGO_ALLOWED_HOSTS }}" DJANGO_SECRET_KEY="${{ secrets.DJANGO_SECRET_KEY }}" EOF # 指定env文件运行docker-compose docker-compose -f prod.yml --env-file .env.prod build docker-compose -f prod.yml --env-file .env.prod up -d # 可选:清理临时文件 rm .env.prod
这种方式不需要依赖shell的环境变量,docker-compose会直接从文件读取变量,稳定性更高。
内容的提问来源于stack exchange,提问作者aletin
相关产品推荐
相关产品推荐

