Nico
Nico

Reputation: 115

Docker Build does not pass secret via --mount=type=secret

Problem

I am using docker/build-push-action@v6 in a GitHub Actions pipeline to build a Docker image. I am trying to pass a pip.conf file as a secret during the build, but --mount=type=secret cannot find the file inside the container.

However, when I run the same command manually using docker buildx build, it works perfectly.


My Setup

GitHub Actions Workflow (.github/workflows/build.yml):

name: Build and push Docker images

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

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

      - name: Configure Python
        run: |
          mkdir -p $GITHUB_WORKSPACE/.config/pip
          touch $GITHUB_WORKSPACE/.config/pip/pip.conf
          chmod 777 $GITHUB_WORKSPACE/.config/pip/pip.conf
          echo "[global]
          extra-index-url = ${{ secrets.CONF }}" > $GITHUB_WORKSPACE/.config/pip/pip.conf

      - name: Build and push Docker images
        uses: docker/build-push-action@v6
        with:
          context: python
          platforms: linux/amd64
          push: false
          pull: true
          tags: myrepo/myimage:latest
          build-args: |
            DOCKER_BUILDKIT=1
            BUILDKIT_INLINE_CACHE=1
          secrets: |
            id=pip,src=$GITHUB_WORKSPACE/.config/pip/pip.conf

Dockerfile

FROM python:3.11-slim

RUN --mount=type=secret,id=pip,target=/etc/pip.conf pip install --no-cache-dir -r requirements.txt

Expected Behavior

The python build should work with no issues.


Actual Behavior

The build failed because private dependencies cannot be found.


What I Have Checked

The pip.conf file exists in the build context and is not empty.
Running the command manually with docker buildx build works perfectly:

docker buildx build   
 --platform linux/amd64 \  
 --pull \
 --build-arg BUILDKIT_INLINE_CACHE=1 \  
 --secret id=pip,src=$GITHUB_WORKSPACE/.config/pip/pip.conf \   
 -t test:123 \  
 python

BuildKit is enabled (DOCKER_BUILDKIT=1).
Debugging with ls confirms that the file exists before the build starts.
This issue only happens with docker/build-push-action@v6.


Question

Why is the secret not passed to the build when using docker/build-push-action@v6, but it works fine with docker buildx build?
Are there known issues with how secrets: are passed in this GitHub Action?
Is there a better way to securely pass pip.conf to the Docker build in this setup?

Any insights would be appreciated. Thanks!

EDIT 20.Feb:

I have further analyzed the issue and found the following insights:

  1. Running docker buildx build directly → works.

The secret is passed correctly, /run/secrets/pip is available.

  1. **Using docker/build-push-action@v5 with secret-files: or

secrets: with the exact same path→ does not work.**
Error: Even though the file exists.

  1. Tried different Paths for the file:

    • $GITHUB_WORKSPACE/.config/pip/pip.conf
    • $GITHUB_WORKSPACE/python/pip.conf
    • $GITHUB_WORKSPACE/pip.conf
    • $HOME/pip.conf
    • /.config/pip/pip.conf
    • python/pip.conf
    • /pip.conf

    → Same Error even though the file exists at every place

I still have no idea what the problem is, and I am considering creating an issue on GitHub.

Upvotes: 1

Views: 72

Answers (3)

Nico
Nico

Reputation: 115

Solution: Why secrets and secret-files were not working in docker/build-push-action@v6

After extensive debugging, I finally found the solution! The main issues were:

1. Incorrect Path Resolution for Secrets

  • ${{ env.GITHUB_WORKSPACE }} is not evaluated correctly in docker/build-push-action@v6.
  • Instead, you should use ${{ github.workspace }}, as it's properly resolved in GitHub Actions.

2. Difference Between secrets and secret-files

  • secrets: expects direct key-value pairs, e.g.:

    secrets: |
      "pip=[global]
      extra-index-url = ${{ secrets.PIP_CONF }}"
    

    This means the secret is passed as a variable inside the container.

  • secret-files: requires a file path, e.g.:

    secret-files: |
      pip=${{ github.workspace }}/.config/pip/pip.conf
    

    This works if the file exists before the build starts.

3. Fixing the Issue

Solution 1: Use secret-files: with the Correct Path

- name: Build and push Docker images
  uses: docker/build-push-action@v6
  with:
    context: python
    secret-files: |
      pip=${{ github.workspace }}/.config/pip/pip.conf

This ensures that the file is correctly passed into BuildKit.

Solution 2: Use secrets: to Pass File Content Directly

If you don't want to create a file manually, you can pass the content directly:

- name: Build and push Docker images
  uses: docker/build-push-action@v6
  with:
    context: python
    secrets: |
      "pip=[global]
      extra-index-url = ${{ secrets.PIP_CONF }}"

This way, the content is injected directly as a secret, avoiding the need for a physical file.


Final Thoughts

  • Using ${{ github.workspace }} instead of ${{ env.GITHUB_WORKSPACE }} was key.
  • Understanding when to use secrets: vs secret-files: helped resolve the issue.
  • Passing the secret directly as a value (secrets:) can be a good alternative if a file is not needed. Big thanks to the community for the insights! Hope this helps others facing the same problem! And a Special Thanks for the Help on the Issue: https://github.com/docker/build-push-action/issues/1326

Upvotes: 1

Szymon Maszke
Szymon Maszke

Reputation: 24914

You want to mount a file (see actions inputs and build secrets in docker's documentation), hence you should use secret-files instead, so (omitted top of the file for brevity):

...
- name: Build and push Docker images
  uses: docker/build-push-action@v6
  with:
    context: python
    platforms: linux/amd64
    push: false
    pull: true
    tags: myrepo/myimage:latest
    build-args: |
      DOCKER_BUILDKIT=1
      BUILDKIT_INLINE_CACHE=1
    secret-files: |
      pip=$GITHUB_WORKSPACE/.config/pip/pip.conf

Upvotes: 0

Dayananda D R
Dayananda D R

Reputation: 443

can you try to spilt lines into two and try once - https://docs.docker.com/build/ci/github-actions/secrets/

- name: Build and push Docker images
        uses: docker/build-push-action@v6
        with:
          context: python
          platforms: linux/amd64
          push: false
          pull: true
          tags: myrepo/myimage:latest
          build-args: |
            DOCKER_BUILDKIT=1
            BUILDKIT_INLINE_CACHE=1
          secrets: |
            "id=pip"
            "src=$GITHUB_WORKSPACE/.config/pip/pip.conf"

Upvotes: 0

Related Questions