將機密與 GitHub Actions 搭配使用

構建密鑰 (Build secret) 是指在構建過程中使用的敏感資訊,例如密碼或 API 金鑰。Docker Build 支援兩種形式的密鑰:

  • 密鑰掛載:將密鑰以檔案形式加入到構建容器中(預設路徑為 /run/secrets)。
  • SSH 掛載:將 SSH 代理 socket 或金鑰加入到構建容器中。

本頁面展示如何在 GitHub Actions 中使用密鑰。關於密鑰的通用介紹,請參閱 構建密鑰

密鑰掛載 (Secret mounts)

以下範例使用了 GitHub 在工作流程 (workflow) 中提供的 GITHUB_TOKEN 密鑰並進行暴露。

首先,建立一個使用該密鑰的 Dockerfile

# syntax=docker/dockerfile:1
FROM alpine
RUN --mount=type=secret,id=github_token,env=GITHUB_TOKEN ...

在此範例中,密鑰名稱為 github_token。以下工作流程使用 secrets 輸入項來暴露此密鑰:

name: ci

on:
  push:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

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

      - name: Build
        uses: docker/build-push-action@v6
        with:
          platforms: linux/amd64,linux/arm64
          tags: user/app:latest
          secrets: |
            "github_token=${{ secrets.GITHUB_TOKEN }}"
注意

您也可以透過 secret-files 輸入項將密鑰檔案暴露給構建過程:

secret-files: |
  "MY_SECRET=./secret.txt"

如果您正在使用 GitHub 密鑰並且需要處理多行數值,則需要將鍵值對用引號括起來:

secrets: |
  "MYSECRET=${{ secrets.GPG_KEY }}"
  GIT_AUTH_TOKEN=abcdefghi,jklmno=0123456789
  "MYSECRET=aaaaaaaa
  bbbbbbb
  ccccccccc"
  FOO=bar
  "EMPTYLINE=aaaa

  bbbb
  ccc"
  "JSON_SECRET={""key1"":""value1"",""key2"":""value2""}"
MYSECRET***********************
GIT_AUTH_TOKENabcdefghi,jklmno=0123456789
MYSECRETaaaaaaaa\nbbbbbbb\nccccccccc
FOObar
EMPTYLINEaaaa\n\nbbbb\nccc
JSON_SECRET{"key1":"value1","key2":"value2"}
注意

引號符號需要雙重轉義。

SSH 掛載 (SSH mounts)

SSH 掛載允許您使用 SSH 伺服器進行身份驗證。例如,執行 git clone,或從私有儲存庫獲取應用程式套件。

以下 Dockerfile 範例使用 SSH 掛載從私有 GitHub 儲存庫獲取 Go 模組。

# syntax=docker/dockerfile:1

ARG GO_VERSION="1.24"

FROM golang:${GO_VERSION}-alpine AS base
ENV CGO_ENABLED=0
ENV GOPRIVATE="github.com/foo/*"
RUN apk add --no-cache file git rsync openssh-client
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
WORKDIR /src

FROM base AS vendor
# this step configure git and checks the ssh key is loaded
RUN --mount=type=ssh <<EOT
  set -e
  echo "Setting Git SSH protocol"
  git config --global url."git@github.com:".insteadOf "https://github.com/"
  (
    set +e
    ssh -T git@github.com
    if [ ! "$?" = "1" ]; then
      echo "No GitHub SSH key loaded exiting..."
      exit 1
    fi
  )
EOT
# this one download go modules
RUN --mount=type=bind,target=. \
    --mount=type=cache,target=/go/pkg/mod \
    --mount=type=ssh \
    go mod download -x

FROM vendor AS build
RUN --mount=type=bind,target=. \
    --mount=type=cache,target=/go/pkg/mod \
    --mount=type=cache,target=/root/.cache \
    go build ...

要構建此 Dockerfile,您必須在步驟中使用 --mount=type=ssh 指定構建器可以使用的 SSH 掛載。

以下 GitHub Action 工作流程使用了第三方 action MrSquaare/ssh-setup-action 來在 GitHub runner 上引導 SSH 設定。該 action 建立了一個由 GitHub Action 密鑰 SSH_GITHUB_PPK 定義的私鑰,並將其添加到位於 SSH_AUTH_SOCK 的 SSH 代理 socket 檔案中。構建步驟中的 SSH 掛載預設會採用 SSH_AUTH_SOCK,因此無需明確指定 SSH 代理 socket 的 ID 或路徑。

name: ci

on:
  push:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Set up SSH
        uses: MrSquaare/ssh-setup-action@2d028b70b5e397cf8314c6eaea229a6c3e34977a # v3.1.0
        with:
          host: github.com
          private-key: ${{ secrets.SSH_GITHUB_PPK }}
          private-key-name: github-ppk

      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          ssh: default
          push: true
          tags: user/app:latest
name: ci

on:
  push:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Set up SSH
        uses: MrSquaare/ssh-setup-action@2d028b70b5e397cf8314c6eaea229a6c3e34977a # v3.1.0
        with:
          host: github.com
          private-key: ${{ secrets.SSH_GITHUB_PPK }}
          private-key-name: github-ppk

      - name: Build
        uses: docker/bake-action@v6
        with:
          set: |
            *.ssh=default
© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.