使用GitHub Actions推送Postgres Docker容器后环境变量为空问题排查
问题:通过GitHub Actions构建Postgres镜像后环境变量为空,容器启动失败
背景
我尝试通过GitHub Actions将Postgres容器推送至Docker Hub,已创建.yml工作流文件、Dockerfile,并在仓库中配置了相关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中写入明文数据库、用户名和密码时一切正常,但改用当前方式后:
- 在Docker Desktop中看到环境变量为空:

- 容器启动时出现错误:
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
相关产品推荐
相关产品推荐

