Files
commit-version/readme.md
T
2026-07-16 03:28:49 +00:00

16 KiB
Raw Blame History

Gitea Docker Container Action 範本

Docker container(容器)action 讓你把整個執行環境打包成一個 Docker image:action 在你指定的容器內執行,環境、相依套件、工具版本全部固定,跨機器結果一致。適合需要特定系統套件、編譯環境或非 JavaScript 語言撰寫的 action。

本文件整理 Docker container action action.yml所有可用參數、說明與限制,包含 Dockerfile 撰寫注意事項,並特別標出 Gitea 與 GitHub Actions 的差異

語法基準:Gitea Actions 以相容 GitHub Actions metadata 語法為目標,但兩者有明確差異(見「Gitea vs GitHub」章節)。Gitea 端的行為亦受底層 act runner 版本影響,實作前建議以測試機驗證。

⚠️ 平台限制Docker container action 只能在 Linux runner 上執行,且該 runner 必須安裝 Docker。Windows / macOS runner 不支援。


目錄


完整結構總覽

name: 'Gitea Docker Template'         # 必填
description: 'Gitea Docker 範本'       # 必填
author: 'Jeffery'                     # 選填

inputs:                               # 選填,定義輸入參數
  message:
    description: '輸入訊息'
    required: false
    default: 'Hello, World!'

outputs:                              # 選填,定義輸出(docker action 只宣告,不用 value
  message:
    description: '輸出訊息'

runs:                                 # 必填
  using: 'docker'                     # 必填,固定為 docker
  image: 'Dockerfile'                 # 必填,本機 Dockerfile 或 docker://image
  # entrypoint: '/entrypoint.sh'      # 選填,覆寫 Dockerfile 的 ENTRYPOINT
  # pre-entrypoint: '/setup.sh'       # 選填,主程式前執行(另開容器)
  # post-entrypoint: '/cleanup.sh'    # 選填,主程式後執行(另開容器)
  env:                                # 選填,容器內環境變數
    GREETING: ${{ inputs.message }}
  args:                               # 選填,傳給 ENTRYPOINT 的參數(取代 CMD
  - ${{ inputs.message }}

branding:                             # 選填(Marketplace 用,Gitea 內部可省略)
  icon: 'activity'
  color: 'blue'

📌 action.yml(或 action.yaml)放在 action repo 根目錄;image: 'Dockerfile' 時,Dockerfile 也放在同一目錄。


頂層參數

參數 必填 說明
name Action 名稱。
description Action 簡短說明。
author 作者名稱。
inputs 輸入參數定義(見下)。
outputs 輸出定義(見下)。
runs 執行設定;docker 固定用 using: 'docker' + image
branding Marketplace 顯示用的 iconcolorcolorwhite/black/yellow/blue/green/orange/red/purple/gray-darkicon 為 Feather 圖示名稱)。

inputs(輸入參數)

每個 input 是 inputs.<input_id> 底下的一組設定:

欄位 必填 說明
description 參數說明。
required 是否必填,布林值,預設 false
default 預設值;呼叫端沒傳時採用。只能是字串
deprecationMessage 標記此 input 已棄用,使用時發出警告訊息。

Docker action 怎麼取用 input

這是 Docker action 與 composite action 最大的差異。GitHub / Gitea 會把每個 input 轉成環境變數 INPUT_<NAME>

  • 名稱轉大寫、空白換成底線。例:input octocat-eye-color → 環境變數 INPUT_OCTOCAT_EYE_COLOR
  • input messageINPUT_MESSAGE
inputs:
  message:
    description: '輸入訊息'
    required: false
    default: 'Hello, World!'

容器內就能直接讀:

echo "$INPUT_MESSAGE"

⚠️ 關鍵限制INPUT_* 環境變數只在 GitHub 官方 runner 保證自動注入。若要跨環境(尤其 Gitea/act)可靠取值,官方建議args 明確把 input 傳進容器,或在 runs.env 自行對應一次(見下方 runs.env)。不要單靠 INPUT_* 而不驗證。

呼叫端傳值(用 with):

- uses: ./
  with:
    message: 'Hi there'

input 值一律是字串;數字、布林傳進來也會變字串(例如 "true"),比較時要留意。


outputs(輸出)

Docker action 的 output 只需宣告 description不用(也不能)像 composite 那樣寫 value

欄位 必填 說明
description 輸出說明。

在容器內設定 output → 寫入 $GITHUB_OUTPUT 檔案(該檔案路徑由 runner 掛載進容器):

outputs:
  message:
    description: '輸出訊息'

entrypoint.sh 內:

echo "message=Hello from docker" >> "$GITHUB_OUTPUT"

呼叫端取用 output

- id: docker-template
  uses: ./
- run: echo "${{ steps.docker-template.outputs.message }}"

📦 output 大小限制:單一 job 的 output 上限 1 MB,整個 workflow run 所有 output 合計上限 50 MB


runs(執行設定)

Docker action 的核心。using 固定為 docker,其餘欄位:

欄位 必填 說明
using 固定為 'docker'
image 要跑的 image:本機 Dockerfile(檔名必須正好是 Dockerfile),或遠端 image 用 docker:// 前綴(如 docker://alpine:3.20docker://gcr.io/...)。
entrypoint 覆寫 Dockerfile 的 ENTRYPOINTDockerfile 沒設時等於補上。建議用絕對路徑(如 /entrypoint.sh)。
pre-entrypoint 在主 entrypoint 之前執行的前置腳本。會另開一個新容器(同 base image),runtime 狀態與主容器不同——需保留的狀態要放進 workspace、HOME,或用 STATE_ 變數傳遞。
post-entrypoint entrypoint 完成後執行的清理腳本,行為同 pre-entrypoint(另開容器)。
pre-if 條件式,控制 pre-entrypoint 是否執行;預設一定跑。
post-if 條件式,控制 post-entrypoint 是否執行;預設一定跑。
args 字串陣列,啟動時傳給容器 ENTRYPOINT 的參數,取代 Dockerfile 的 CMD
env key/value map,容器啟動時設定的環境變數。

imageDockerfile vs 遠端 image

# 用本機 Dockerfile(每次執行前會 build
runs:
  using: 'docker'
  image: 'Dockerfile'

# 直接拉遠端 image(不用自帶 Dockerfile,啟動快)
runs:
  using: 'docker'
  image: 'docker://alpine:3.20'

args:怎麼把值送進容器

args 取代 CMD,會被當作參數接在 ENTRYPOINT 後面:

runs:
  using: 'docker'
  image: 'Dockerfile'
  args:
  - ${{ inputs.message }}     # → entrypoint.sh 的 $1
  - 'foo'                      # → $2
  - 'bar'                      # → $3

⚠️args 裡放的是環境變數字串(如 - $GREETING),在 exec-form 的 ENTRYPOINT 不會被展開。要展開變數,讓 entrypoint 走一層 shellsh -c),或改用 runs.env 傳值(見下)。

env:明確傳環境變數(推薦)

比起依賴 INPUT_* 自動注入,用 runs.env 把 input 對應成自訂環境變數,跨環境最穩:

runs:
  using: 'docker'
  image: 'Dockerfile'
  env:
    GREETING: ${{ inputs.message }}

容器內直接 echo "$GREETING"


Dockerfile 撰寫注意事項

Docker action 的 Dockerfile 有幾條強制或強烈建議的規則,踩到會直接失敗或讀不到檔案:

  1. FROM 必須是第一行 建議用官方 image + 明確版本標籤(如 python:3.12-slim),別用 latestDebian/Alpine 系列較穩。

  2. 不要用 USER Docker action 必須以預設的 root 執行。加了 USER 會導致無法存取 GITHUB_WORKSPACE(掛載進來的 repo 目錄)。

  3. 不要用 WORKDIR 指定 entrypoint 位置 runner 會自動把 GITHUB_WORKSPACE 掛載上來並設為工作目錄(路徑放在 $GITHUB_WORKSPACE 環境變數)。entrypoint/腳本一律用絕對路徑(如 /entrypoint.sh),不要依賴 WORKDIR

  4. ENTRYPOINT 用 exec formJSON 陣列) Docker 官方建議寫 ENTRYPOINT ["/entrypoint.sh"]

    • exec formargs 能正確以獨立參數傳入,但不做環境變數展開ENTRYPOINT ["echo", "$GITHUB_SHA"] 印出的是字面字串)。
    • shell formENTRYPOINT /entrypoint.sh 會走 shell,可展開變數,但 args 傳遞行為不同。
    • 需要在 entrypoint 展開變數時,用 ENTRYPOINT ["sh", "-c", "echo $GITHUB_SHA"],或寫一支 entrypoint.sh 腳本自行處理。
  5. CMD 會被 args 蓋掉 action.ymlargs 取代 CMD。若 action 允許不帶 args 也能跑,就在 DockerfileCMD 提供預設值,並在 README 說明必要參數。

  6. entrypoint.sh 腳本規範

    • 開頭要有 shebang#!/bin/sh(或 #!/bin/bash,視 base image 而定)。
    • 要可執行:chmod +x entrypoint.sh(並在 git 中保留執行權限)。
    • 腳本會收到 action.ymlargs 作為位置參數($1, $2, …)。

Docker action 的限制與注意事項

以下是實務上最容易踩雷的地方:

  1. 只能跑在 Linux runner,且要有 Docker Windows / macOS runner 一律不支援 Docker container action。

  2. INPUT_* 不保證可靠,優先用 args / env GitHub 官方 runner 會自動注入 INPUT_<NAME>,但這在自架 / Gitea 環境未必成立。要穩定取 input,用 args 傳位置參數,或 runs.env 對應成自訂環境變數。

  3. pre-entrypoint / post-entrypoint 是「另開容器」 它們不共用主 entrypoint 容器的 runtime 狀態(不是同一個容器內的前後腳本)。要跨階段保留狀態,寫進 GITHUB_WORKSPACEHOME,或用 STATE_ 變數。

  4. 本機 image: 'Dockerfile' 每次會 build 用本機 Dockerfile 時,執行前會先 build image,較慢;想加速可改用 docker:// 拉預先建好的 image。

  5. 只有 GITHUB_WORKSPACE 是持久且共用的 容器內對檔案系統的改動,通常只有掛載進來的 GITHUB_WORKSPACE 會被後續 step 看到;其他路徑(如 /tmp)在跨 step / 跨 action 時不保證保留。

  6. exec-form ENTRYPOINT 不展開變數 如上「Dockerfile 注意事項」第 4 點,需要展開就走 sh -c 或 entrypoint 腳本。

  7. args 是字串陣列,順序即位置參數 args 的順序對應 entrypoint 的 $1, $2…;輸入值全是字串。

  8. 不支援 runs.steps 那是 composite action 專屬。Docker action 只有一個容器進入點(entrypoint)+選配的 pre/post。


Gitea vs GitHub Actions 差異

Gitea Actions 不是 GitHub Actions 的 100% 複製品。撰寫 Docker action 時特別注意:

項目 Gitea 行為
runner 需求 執行 Docker action 的 act_runner 主機必須裝 Docker,且 runner label 對應到支援容器的環境。runs-on 只接受 runs-on: xyzruns-on: [xyz],不支援複雜表達式。
pre-entrypoint / post-entrypoint ⚠️ 早期 act 版本完全不執行 pre/post-entrypoint(見 nektos/act#2363,已於 PR #2394 修復)。Gitea 內建的 act 版本若較舊可能仍無效——使用前務必在測試機驗證
INPUT_* 注入 是否自動注入 INPUT_<NAME> 取決於 runner 版本,別假設一定有;優先用 args / env 明確傳值。
表達式函式 依官方比較文件,僅保證支援 always()success() / failure() / cancelled() / hashFiles() 等視 act runner 版本而定,寫 if:(含 pre-if / post-if)前先在測試機驗證。
uses 支援絕對 URL 可寫 uses: https://github.com/owner/repo@v1uses: http://your_gitea/owner/repo@branch,不限同站 action。
Go actions Gitea 額外支援 using: 'go' 寫 Go actionGitHub 沒有);docker / node / composite 皆支援。
context 檢查較寬鬆 Gitea 不檢查 context 可用性,env context 可用在比 GitHub 更多的位置(但不代表可攜,跨到 GitHub 會失敗)。
被忽略的 job 欄位 jobs.<job_id>.timeout-minutesjobs.<job_id>.continue-on-errorjobs.<job_id>.environment 會被忽略。
annotations / problem matchers 不支援,會被忽略。
permissions scope 支援 permissions,但沒有 GitHub 專屬的 statuses / checks / deployments / id-token / security-events / pagesGitea 有自己的 code / releases / wiki / projects

上表以 Gitea 官方文件為準;act runner 持續更新,部分限制(尤其表達式函式與 pre/post-entrypoint)可能隨版本放寬,仍以你環境的實測為準。


本 repo 範例對照

一個典型 Docker container action 由三個檔案組成,放在 repo 根目錄:

1. action.yml — action 定義

name: 'Gitea Docker Template'
description: 'Gitea Docker 範本'
author: 'Jeffery'
inputs:
  message:
    description: '輸入訊息'
    required: false
    default: 'Hello, World!'
outputs:
  message:
    description: '輸出訊息'
runs:
  using: 'docker'
  image: 'Dockerfile'
  args:
  - ${{ inputs.message }}

2. Dockerfile — 執行環境

FROM alpine:3.20

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

3. entrypoint.sh — 主程式

#!/bin/sh
set -e

# $1 來自 action.yml 的 args(呼叫端 with.message
MESSAGE="$1"

echo "Docker action 收到訊息:$MESSAGE"

# 設定 output 供後續 step 使用
echo "message=$MESSAGE" >> "$GITHUB_OUTPUT"

呼叫端workflow)用法:

- name: 3. Testing
  id: docker-template
  uses: ./
  with:
    message: 'Hi there'
- name: 4. Feedback
  run: echo "${{ steps.docker-template.outputs.message }}"

本 repo 目前的 action.yml 仍為 composite 範本;要改為 Docker action,依上方三件套調整 action.yml 並新增 Dockerfileentrypoint.sh


參考來源