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

使用GitHub Actions推送Postgres Docker容器后环境变量为空问题排查

问题:通过GitHub Actions构建Postgres镜像后环境变量为空,容器启动失败

背景

我尝试通过GitHub Actions将Postgres容器推送至Docker Hub,已创建.yml工作流文件、Dockerfile,并在仓库中配置了相关Secrets:

已配置的Secrets

Secrets配置截图

Dockerfile内容

FROM postgres:latest

ENV POSTGRES_USER=${POSTGRES_USER}
ENV POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
ENV POSTGRES_DB=${POSTGRES_DATABASE}

GitHub Actions工作流文件

name: Build and Push Docker Image to Docker Hub

on:
  push:
    branches: [ "production/*" ]

jobs:
  push_to_registry:
    name: Push Docker image to Docker Hub
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repo
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
        with:
          images: /* my image path */
      - name: Build and push Docker image
        uses: docker/build-push-action@v2
        with:
          context: .
          push: true
          file: ./dockerfiles/postgres-amp-api/Dockerfile
          labels: ${{ steps.meta.outputs.labels }}
          tags: ${{ steps.meta.outputs.tags }}
          secrets: |
            "POSTGRES_USER=${{ secrets.DOCKER_POSTGRES_API_USER }}"
            "POSTGRES_PASSWORD=${{ secrets.DOCKER_POSTGRES_API_PASSWORD }}"
            "POSTGRES_DATABASE=${{ secrets.DOCKER_POSTGRES_API_DB }}"

问题现象

此前在Dockerfile中写入明文数据库、用户名和密码时一切正常,但改用当前方式后:

  1. 在Docker Desktop中看到环境变量为空:
    Docker Desktop环境变量为空截图
  2. 容器启动时出现错误:

Error: Database is uninitialized and superuser password is not specified.
You must specify POSTGRES_PASSWORD to a non-empty value for the
superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".

You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
   connections without a password. This is *not* recommended.

请问我是否遗漏了什么步骤?是否存在未注意到的语法错误?


问题原因及解决方法

核心问题:Docker Build Secrets的使用方式错误

你当前用docker/build-push-action的secrets字段传递的是构建时秘密,但你的Dockerfile并没有读取这些构建秘密,而是直接引用了环境变量,导致构建时这些变量没有被正确注入。

正确的实现方式有两种:

方式一:使用构建参数(Build Args)传递(推荐,适合镜像构建时固化环境变量)

修改Dockerfile,用ARG定义构建参数,再赋值给ENV:

FROM postgres:latest

# 定义构建参数
ARG POSTGRES_USER
ARG POSTGRES_PASSWORD
ARG POSTGRES_DATABASE

# 将构建参数赋值给环境变量
ENV POSTGRES_USER=${POSTGRES_USER}
ENV POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
ENV POSTGRES_DB=${POSTGRES_DATABASE}

然后修改GitHub Actions工作流中的build-push-action步骤,用build-args传递参数:

- name: Build and push Docker image
  uses: docker/build-push-action@v2
  with:
    context: .
    push: true
    file: ./dockerfiles/postgres-amp-api/Dockerfile
    labels: ${{ steps.meta.outputs.labels }}
    tags: ${{ steps.meta.outputs.tags }}
    build-args: |
      POSTGRES_USER=${{ secrets.DOCKER_POSTGRES_API_USER }}
      POSTGRES_PASSWORD=${{ secrets.DOCKER_POSTGRES_API_PASSWORD }}
      POSTGRES_DATABASE=${{ secrets.DOCKER_POSTGRES_API_DB }}

方式二:容器启动时传递环境变量(适合需要动态配置的场景)

如果不想在镜像中固化这些敏感信息,不要在Dockerfile中设置ENV,而是在启动容器时通过-e参数传递:

docker run -d \
  -e POSTGRES_USER=your_user \
  -e POSTGRES_PASSWORD=your_password \
  -e POSTGRES_DB=your_db \
  your-image-tag

同时,需要移除Dockerfile中的ENV行,只保留基础镜像:

FROM postgres:latest

额外注意事项

  • 你的docker/metadata-action步骤中images字段的值是/* my image path */,需要替换成你实际的Docker Hub镜像路径,比如your-docker-username/postgres-amp-api,否则镜像标签会不正确。
  • 构建时秘密(secrets字段)是用于在构建过程中临时访问敏感文件或数据的,比如从私有仓库拉取依赖,不适合直接传递环境变量,所以不建议用这种方式处理Postgres的配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:48:23