📖

Synology NASでGitea + Woodpecker CIを構築してみた

に公開

はじめに

個人開発環境を強化したくてSynology NAS(DS224+)を導入しました。
目的は「自宅にデータの蓄積場所、GitとCI/CD環境を構築する」こと。
この記事では、NASにGiteaとWoodpecker CIをNAS上で構築し、実際にCIが動作するまでの記録をまとめます。

特に、Webhookがうまく飛ばずに詰まった部分は、多くの人がハマりやすいポイントだと思うので、同じ構成を目指す方の参考になれば幸いです。

環境構成

  • NAS: Synology DS224+
  • Gitea: 自前ホスト (docker)
  • Woodpecker CI: docker
  • OS: DSM 7.x(Synology標準)
  • アクセス: ローカルIP(例:192.168.11.7)

開発端末

  • Windows 11(VSCode、SSH、WSL)
  • Gitクライアント(VSCode内蔵)

前提

  • DS224+のDSM上ですでにDokcerクライアントがインストールされていること

Giteaの構築

/volume1/docker/giteaに以下のファイルを作成
docker-compose.yml

version: '3'

services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    restart: always
    ports:
      - "3000:3000"
      - "222:22"
    volumes:
      - ./data:/data
      # 以下は、後で有効にします
      #- ./conf/app.ini:/data/gitea/conf/app.ini
    environment:
      - USER_UID=1024
      - USER_GID=100

まずはこの状態で、

sudo docker-compose up -d

でGiteaを立ち上げます。

Webブラウザで初回設定をして、適当なリポジトリを追加してください(これ自体はGitHub等のそれと大きく変わらないです)

重要ポイント:設定ファイルの追記
Giteaで生成された設定ファイル(/data/gitea/conf/app.ini)をホスト側にコピーしておきます

sudo docker cp gitea:/data/gitea/conf/app.ini ./conf/app.ini

設定ファイルの末尾に任意のエディタ(vimやnano等)で以下を追記します。(もしwebhookの部分があったらそこに追記してください)

[webhook]
ALLOWED_HOST_LIST=external,loopback,(ローカルIP)
ALLOW_LOCAL_NETWORKS = true

Giteaコンテナを再起動します

sudo docker-compose restart

OAuth2アプリケーションの設定

GiteaのWebUI上でOAuth2アプリケーションの設定をします。(WoodpeckerがGiteaにアクセスするために必要です)
Giteaの右上のアバターアイコンから「設定」→「アプリケーション」→「OAuth2アプリケーションの管理」で新しいOAuth2アプリケーションを設定します。
アプリケーション名:Woodpecker
リダイレクトURI:http://(ローカルIP)/authorize
コンフィデンシャルクライアント~のチェックボックスをオン
と設定して「アプリケーション作成」ボタンを押す。
クライアントIDとクライアントシークレットが表示されるのでコピペしておく(Woodpeckerの設定で使います。特にクライアントシークレットは一度別のページに行くと二度と見れなくなるので注意!)

Woodpecker CIの構築

/volume1/docker/woodpeckerに以下のファイルを作成

docker-compose.yml

version: '3'

services:
  woodpecker-server:
    image: woodpeckerci/woodpecker-server:latest
    container_name: woodpecker-server
    restart: always
    ports:
      - "8000:8000"
      - "9000:9000"
    environment:
      - WOODPECKER_OPEN=true
      - WOODPECKER_HOST=http://(ローカルIP):8000
      - WOODPECKER_GITEA=true
      - WOODPECKER_GITEA_URL=http://(ローカルIP):3000
      - WOODPECKER_GITEA_CLIENT=(Giteaのclient_id)
      - WOODPECKER_GITEA_SECRET=(Giteaのclient_secret)
      - WOODPECKER_AGENT_SECRET=(適当な文字列)
      - WOODPECKER_WEBHOOK_ALLOWED_HOST_LIST=(ローカルIP)
    volumes:
      - woodpecker-data:/var/lib/woodpecker

  woodpecker-agent:
    image: woodpeckerci/woodpecker-agent:latest
    container_name: woodpecker-agent
    restart: always
    depends_on:
      - woodpecker-server
    environment:
      - WOODPECKER_SERVER=woodpecker-server:9000
      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

volumes:
  woodpecker-data:

environmentは.envに分離して、読み込む形でもOK!
WOODPECKER_GITEA_CLIENT、WOODPECKER_GITEA_SECRETは、OAuth2アプリケーションの設定で得られたクライアントIDとクライアントシークレットを入れればOK。

sudo docker-compose up -d

でWoodpeckerのコンテナを起動して
http://(ローカルIP):8000
にアクセスして認証を通す。

これで、WoodpecckerのWebUI上でGitea上のリポジトリが参照できるようになっているはずなので、CIを回したい対象のリポジトリを選択する。

CIを動かす

リポジトリのルートに例えば以下のような設定ファイルを作成する。
(echoとpythonのバージョンを出力するだけの簡単なCI)
.woodpecker.yml

pipeline:
  test:  # 任意のステップ名
    image: python:3.11  # 使用するDockerイメージ
    commands:
      - echo "Woodpecker CI is working!"  # 実行するコマンド(echo)
      - python --version  # 実行するコマンド(python)

commitして、pushする。
CIが走る(Woodpecker WebUI上で確認できる)。

詰まったところ

Webhookが飛ばない
原因:Giteaのapp.iniが正しくマウントされていなかった。

  • ALLOW_LOCAL_NETWORKS = true を /data/gitea/conf/app.ini に追記
  • マウント設定を明示的に volumes: に書くこと
volumes:
  - ./conf/app.ini:/data/gitea/conf/app.ini

Webhook URLが拒否される
ログに以下が出た場合:

webhook can only call allowed HTTP servers (check your webhook.ALLOWED_HOST_LIST setting)

→ ALLOW_LOCAL_NETWORKS が効いていない(設定場所ミス)可能性が高いです。

将来的に

この仕組みを使って成果物をローカル内に展開したり、AWS S3にアップロード等、自宅での開発を効率化させる取り組みをしていきたいと考えています。

おわりに

CIが自宅NASで動くんだってことで、低コストで自分の実験場を作るための一歩を踏み出した感覚です。
Gitea + Woodpecker CI軽量なのでぜひ試してみてください!

この記事が誰かの助けになれば幸いです。

Discussion