16 KiB
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 端的行為亦受底層
actrunner 版本影響,實作前建議以測試機驗證。⚠️ 平台限制:Docker container action 只能在 Linux runner 上執行,且該 runner 必須安裝 Docker。Windows / macOS runner 不支援。
目錄
- 完整結構總覽
- 頂層參數
inputs(輸入參數)outputs(輸出)runs(執行設定)Dockerfile撰寫注意事項- Docker action 的限制與注意事項
- Gitea vs GitHub Actions 差異
- 本 repo 範例對照
- 參考來源
完整結構總覽
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 顯示用的 icon 與 color(color 限 white/black/yellow/blue/green/orange/red/purple/gray-dark;icon 為 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
message→INPUT_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.20、docker://gcr.io/...)。 |
entrypoint |
❌ | 覆寫 Dockerfile 的 ENTRYPOINT;Dockerfile 沒設時等於補上。建議用絕對路徑(如 /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,容器啟動時設定的環境變數。 |
image:Dockerfile 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 走一層 shell(sh -c),或改用runs.env傳值(見下)。
env:明確傳環境變數(推薦)
比起依賴 INPUT_* 自動注入,用 runs.env 把 input 對應成自訂環境變數,跨環境最穩:
runs:
using: 'docker'
image: 'Dockerfile'
env:
GREETING: ${{ inputs.message }}
容器內直接 echo "$GREETING"。
Dockerfile 撰寫注意事項
Docker action 的 Dockerfile 有幾條強制或強烈建議的規則,踩到會直接失敗或讀不到檔案:
-
FROM必須是第一行 建議用官方 image + 明確版本標籤(如python:3.12-slim),別用latest;Debian/Alpine 系列較穩。 -
不要用
USERDocker action 必須以預設的 root 執行。加了USER會導致無法存取GITHUB_WORKSPACE(掛載進來的 repo 目錄)。 -
不要用
WORKDIR指定 entrypoint 位置 runner 會自動把GITHUB_WORKSPACE掛載上來並設為工作目錄(路徑放在$GITHUB_WORKSPACE環境變數)。entrypoint/腳本一律用絕對路徑(如/entrypoint.sh),不要依賴WORKDIR。 -
ENTRYPOINT用 exec form(JSON 陣列) Docker 官方建議寫ENTRYPOINT ["/entrypoint.sh"]。- exec form:
args能正確以獨立參數傳入,但不做環境變數展開(ENTRYPOINT ["echo", "$GITHUB_SHA"]印出的是字面字串)。 - shell form:
ENTRYPOINT /entrypoint.sh會走 shell,可展開變數,但args傳遞行為不同。 - 需要在 entrypoint 展開變數時,用
ENTRYPOINT ["sh", "-c", "echo $GITHUB_SHA"],或寫一支entrypoint.sh腳本自行處理。
- exec form:
-
CMD會被args蓋掉action.yml的args取代CMD。若 action 允許不帶args也能跑,就在Dockerfile的CMD提供預設值,並在 README 說明必要參數。 -
entrypoint.sh腳本規範- 開頭要有 shebang:
#!/bin/sh(或#!/bin/bash,視 base image 而定)。 - 要可執行:
chmod +x entrypoint.sh(並在 git 中保留執行權限)。 - 腳本會收到
action.yml的args作為位置參數($1,$2, …)。
- 開頭要有 shebang:
Docker action 的限制與注意事項
以下是實務上最容易踩雷的地方:
-
只能跑在 Linux runner,且要有 Docker Windows / macOS runner 一律不支援 Docker container action。
-
INPUT_*不保證可靠,優先用args/envGitHub 官方 runner 會自動注入INPUT_<NAME>,但這在自架 / Gitea 環境未必成立。要穩定取 input,用args傳位置參數,或runs.env對應成自訂環境變數。 -
pre-entrypoint/post-entrypoint是「另開容器」 它們不共用主 entrypoint 容器的 runtime 狀態(不是同一個容器內的前後腳本)。要跨階段保留狀態,寫進GITHUB_WORKSPACE、HOME,或用STATE_變數。 -
本機
image: 'Dockerfile'每次會 build 用本機 Dockerfile 時,執行前會先 build image,較慢;想加速可改用docker://拉預先建好的 image。 -
只有
GITHUB_WORKSPACE是持久且共用的 容器內對檔案系統的改動,通常只有掛載進來的GITHUB_WORKSPACE會被後續 step 看到;其他路徑(如/tmp)在跨 step / 跨 action 時不保證保留。 -
exec-form
ENTRYPOINT不展開變數 如上「Dockerfile 注意事項」第 4 點,需要展開就走sh -c或 entrypoint 腳本。 -
args是字串陣列,順序即位置參數args的順序對應 entrypoint 的$1,$2…;輸入值全是字串。 -
不支援
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: xyz 或 runs-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@v1 或 uses: http://your_gitea/owner/repo@branch,不限同站 action。 |
| Go actions | Gitea 額外支援 using: 'go' 寫 Go action(GitHub 沒有);docker / node / composite 皆支援。 |
| context 檢查較寬鬆 | Gitea 不檢查 context 可用性,env context 可用在比 GitHub 更多的位置(但不代表可攜,跨到 GitHub 會失敗)。 |
| 被忽略的 job 欄位 | jobs.<job_id>.timeout-minutes、jobs.<job_id>.continue-on-error、jobs.<job_id>.environment 會被忽略。 |
| annotations / problem matchers | 不支援,會被忽略。 |
permissions scope |
支援 permissions,但沒有 GitHub 專屬的 statuses / checks / deployments / id-token / security-events / pages;Gitea 有自己的 code / releases / wiki / projects。 |
上表以 Gitea 官方文件為準;
actrunner 持續更新,部分限制(尤其表達式函式與 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並新增Dockerfile、entrypoint.sh。