はじめに
この記事はGiteaを使ったCI/CDパイプラインの構築方法を展開する連載の一つである。
連載の各記事へは以下からジャンプできる。
- Giteaインストール編
- アプリケーション構築編
- テスト編
- ビルド編
- デプロイ編
CI/CDパイプラインでビルドを実行する
この記事では以下の赤枠部である、ビルドの自動実行をやってみよう。
Packagesを読み書きするためのアクセストークンを発行する
GiteaにはPackagesという機能があり、そこにDockerイメージを登録することができる。
Act Runnerはアクセストークンを使えばPackagesを読み書きできる。
アクセストークンを発行するために、以下のように画面右上のSettingsを選択する。
以下のように左にあるメニューからApplicationsを選択する。
Token Nameに任意の名前を入力し、packageとrepositoryの読み書きを有効にした上でGenerate Tokenボタンを押下する。
以下のように画面上にトークンが表示されるのでコピーする。
リポジトリのSettingsに移動して、左のメニューにあるActions-Secretsを選択する。
Add secretのボタンを押下する。
以下のようにダイアログが表示されるので、NameにPERSONAL_ACCESS_TOKEN、Valueに先ほどコピーしたアクセストークンを貼り付け、Confirmのボタンを押下する。
Dockerイメージをビルドできるようにする
アプリケーションのDockerfileを作成する。
.
+├── Dockerfile
├── README.md
├── package-lock.json
├── package.json
├── src
│ ├── app.test.ts
│ ├── app.ts
│ ├── index.ts
│ ├── sum.test.ts
│ └── sum.ts
├── tsconfig.json
└── vitest.config.ts
# ビルドステージ
FROM node:24.14.1 AS build
WORKDIR /app
# 依存関係をインストールする
COPY package.json package-lock.json ./
RUN npm ci
# ソースコードをコピーしてビルドする
COPY . .
RUN npm run build
# プロダクションステージ
FROM node:24.14.1-slim AS production
ENV NODE_ENV=production
WORKDIR /app
# 本番用の依存関係のみインストールする
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
# ビルド成果物をコピーする
COPY --from=build /app/dist ./dist
# アプリケーションを起動する
CMD ["node", "dist/index.js"]
手元でイメージをビルドし、動作を確認しておく。
# Dockerイメージをビルドする
$ docker build -t $(node -p "require('./package.json').name"):$(node -p "require('./package.json').version") .
[+] Building 8.1s (18/18) FINISHED
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 793B
=> [internal] load metadata for docker.io/library/node:24.14.1-slim
=> [internal] load metadata for docker.io/library/node:24.14.1
# 以下略
# Dockerイメージの一覧を確認する
$ docker images
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
cicd-example:1.0.0 2fa08a2e94f6 227MB 0B
# Dockerコンテナを起動する
$ docker run -p 3030:3000 cicd-example:1.0.0
Server is running on http://localhost:3000
Webブラウザでhttp://localhost:3030にアクセスしたとき、以下のように1+1の結果が返ってきたらDockerイメージは正常に動作している。
Workflowにビルドのジョブを追加する
.gitea/workflows/workflow.ymlにbuildのジョブを追加する。
このジョブはDockerfileのビルドを行い、イメージをPackagesへプッシュする。
name: Workflow
on:
push:
branches:
- main # mainブランチに対して実行する
env:
NODE_VERSION: "24.14.1" # 使用するNode.jsのバージョンを定義する
jobs:
typecheck:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install dependencies
run: npm ci
- name: Run typecheck
run: npm run typecheck
test:
needs: typecheck # typecheckが通ったら実行する
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install dependencies
run: npm ci
- name: Run test
run: npm run test
+ build:
+ runs-on: ubuntu-latest
+ needs: [typecheck, test] # typecheckとtestが通ったら実行する
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+ - name: Use Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+ # Docker BuildxにHTTPのコンテナレジストリへのpushを許可する
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ with:
+ buildkitd-config-inline: |
+ [registry."${{ vars.REGISTRY_ENDPOINT }}"]
+ http = true
+ insecure = true
+ # コンテナレジストリへの認証情報を設定する
+ - name: Log in to Gitea container registry
+ run: |
+ mkdir -p ~/.docker
+ AUTH=$(echo -n "${{ gitea.actor }}:${{ secrets.PERSONAL_ACCESS_TOKEN }}" | base64 -w 0)
+ echo "{\"auths\":{\"${{ vars.REGISTRY_ENDPOINT }}\":{\"auth\":\"$AUTH\"}}}" > ~/.docker/config.json
+ - name: Build and push
+ run: |
+ IMAGE_NAME=$(node -p "require('./package.json').name")
+ TAG_NAME=$(node -p "require('./package.json').version")
+ docker buildx build \
+ --platform linux/amd64,linux/arm64 \
+ --tag ${{ vars.REGISTRY_ENDPOINT }}/${{ gitea.repository_owner }}/$IMAGE_NAME:$TAG_NAME \
+ --tag ${{ vars.REGISTRY_ENDPOINT }}/${{ gitea.repository_owner }}/$IMAGE_NAME:latest \
+ --cache-from type=registry,ref=${{ vars.REGISTRY_ENDPOINT }}/${{ gitea.repository_owner }}/$IMAGE_NAME:buildcache \
+ --cache-to type=registry,ref=${{ vars.REGISTRY_ENDPOINT }}/${{ gitea.repository_owner }}/$IMAGE_NAME:buildcache,mode=max \
+ --provenance=false \
+ --push \
+ .
buildのジョブでは以下のことを行っている。
- リポジトリをチェックアウトする
- Node.js環境を用意する
- Dockerイメージをマルチアーキテクチャでビルドし、Gitea Packagesにプッシュする
以下のようにリポジトリのSettingsにあるActions-Variablesにアクセスし、Add Variableのボタンを押下する。
登録先レジストリとしてGiteaのホストを追加する。(xxx.xxx.xxx.xxx:yyyyの形式で指定する)
リポジトリに変更内容をプッシュする。
$ git add -A
$ git commit -m "buildのジョブを定義した"
$ git push
CI/CDパイプラインが動作することを確認する。
ビルドしたイメージをリポジトリのPackagesに紐づける
CI/CDパイプラインからDockerイメージをプッシュしても以下の通りリポジトリのPackagesの画面には表示されない。
Dockerイメージを初めてプッシュしたときは、リポジトリのPackagesにDockerイメージを紐づける手順が必要となる。(2回目以降は要らない)
上の画面のpackage settingsのリンクを押下し、イメージ名を選択する。
以下の画面右下にあるSettingsを選択する。
以下の通りLink this package to a repositoryの欄にリポジトリ名を入力し、Update Repository Linkのボタンを押下する。
再度リポジトリのPackagesへアクセスし、Dockerイメージが登録されていることを確認する。
Dockerイメージを実行する
ローカル環境でDockerイメージを取得し、コンテナとして実行してみる。${Giteaホスト}にはxxx.xxx.xxx.xxx:yyyyの形式でGiteaのホストを指定する。
$ docker run -p 3030:3000 ${Giteaホスト}/kkawaharanet/cicd-example:latest
Dockerはデフォルトの設定ではHTTPのレジストリと通信しようとするとエラーになる。
$ docker run -p 3030:3000 xxx.xxx.xxx.xxx:yyyy/kkawaharanet/cicd-example:latest
Unable to find image 'xxx.xxx.xxx.xxx:yyyy/kkawaharanet/cicd-example:latest' locally
docker: Error response from daemon: Get "https://xxx.xxx.xxx.xxx:yyyy/v2/": http: server gave HTTP response to HTTPS client
Run 'docker run --help' for more information
この場合/etc/docker/daemon.jsonに以下の設定をマージする。
{
"insecure-registries": ["xxx.xxx.xxx.xxx:yyyy"]
}
Dockerデーモンを再起動する。
sudo systemctl restart docker.service docker.socket
再度コンテナの起動を試す。
$ docker run -p 3030:3000 xxx.xxx.xxx.xxx:yyyy/kkawaharanet/cicd-example:latest
Server is running on http://localhost:3000
Webブラウザでhttp://xxx.xxx.xxx.xxx:yyyy/sumにアクセスしたとき、1+1の結果が返ってきたら、GiteaのPackagesからDockerイメージを取得することに成功している。
振り返り
- Docker Composeを使ってAct Runnerを構築することができた
- Gitea ActionsのCI/CDパイプラインでDockerイメージをビルドしPackagesに登録することができた
- Packagesに登録したDockerイメージをコンテナとして実行することができた
次回
次回はCI/CDパイプライン上でデプロイを行う。














