M6 Mac miniを書いました!
ので、CIサーバーとして活用します。
環境を汚さずに日常使いも同時にできるCIサーバーを作る
せっかくのApple Siliconなので、Linux CIに加えてmacOS CIにもします。
CIサーバーにするのは前々からの目的ではあるものの、CIだけにはもったいないので、日常使いもできるようにします。
しかし、CIに環境を汚されてしまっては困ります。なのでマルチユーザーかつコンテナ/VMで隔離されたCI環境を作ります。
構成検討
以前のmacOS CIサーバーはOrbStackを使用してdocker互換socketを生やしていましたが、OrbStackはGUI前提のようなアプリのため今回は別のものを使用します。
Apple Containerというものがちょっと前に公式から出て流行っていた雰囲気があるので調査しましたが、どうやらDockerやDocker Composeとの互換性がまだ不十分のようなのでCI用途には不採用としました。
そこで、ColimaをDockerランタイムに使用します。
また、macOS Runnerも必要です。
しかし、macOS RunnerをMac miniのホスト上で直接動作させるとCIによってホスト環境が汚染されます。
そこでTartというものを見つけました。どうやらOpenAI(に移管された?)が作っているようです。
これはmacOS VMをCLIから簡単に管理、作成できるようなツールになっています。
ユーザーを分離する
普段遣いのAdministratorユーザーのsim1222と、CI向け一般ユーザーのciを作成した。
Homebrewをどうしよう
ColimaやTartはパッケージマネージャーなどから導入したいため、homebrewが選択肢に挙がります。
しかし、homebrewはデフォルトで/opt/homebrewなどを使用するため、普通にマルチユーザーにすると管理が大変になります。
なので、
- メインのユーザーでhomebrew経由でtartやColimaなどの必要なツールをインストール
- ciユーザーのpathに
/opt/homebrew/bin/を通す - ciはhomebrewを触らないが、homebrew経由でパッケージが管理される
ようにしました。
Colimaでdocker socketを生やす
まず、普段のユーザーからColimaをインストールします。
brew install colimadockerコマンドとそのランタイムは別なのでdockerコマンドもインストールします
brew install docker docker-composedockerコマンドからCompose Pluginを見つけられるようにします。
~/.docker/config.json
{ "cliPluginsExtraDirs": [ "/opt/homebrew/lib/docker/cli-plugins" ]}Colimaを自動起動する
通常であれば、この後に
brew services start colimaでLaunchAgentでColimaを自動起動させますが、homebrewで複数ユーザーかつcolimaを動作させるのが通常権限ユーザーだとログの書き込みに失敗して落ちます。
Homebrewが生成するLaunchAgentのplistは、/opt/homebrew/var/log/colima.logにログを書き込もうとしますが、当然そこへの書き込み権限はありません。
/opt/homebrew/var/log/の権限を緩めてもいいですが、今回は普段使いユーザーでもcolimaを使いたいのでログが衝突してしまう危険性があります。
なので、自動生成のLaunchAgentのplistではなく、それをベースに自分で書きます。
今回はログを/Users/ci/Library/Logs/colima.logに置きます。
/Users/ci/Library/LaunchAgents/com.sim1222.ci-colima.plist
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>Label</key> <string>com.sim1222.ci-colima</string>
<key>ProgramArguments</key> <array> <string>/opt/homebrew/opt/colima/bin/colima</string> <string>start</string> <string>-f</string> </array>
<key>WorkingDirectory</key> <string>/Users/ci</string>
<key>EnvironmentVariables</key> <dict> <key>HOME</key> <string>/Users/ci</string> <key>PATH</key> <string>/opt/homebrew/bin:/opt/homebrew/sbin:/usr/bin:/bin:/usr/sbin:/sbin</string> <key>COLIMA_HOME</key> <string>/Users/ci/.colima</string> </dict>
<key>RunAtLoad</key> <true/>
<key>KeepAlive</key> <dict> <key>SuccessfulExit</key> <true/> </dict>
<key>StandardOutPath</key> <string>/Users/ci/Library/Logs/colima.log</string>
<key>StandardErrorPath</key> <string>/Users/ci/Library/Logs/colima.log</string></dict></plist>そして登録、起動します
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.sim1222.ci-colima.plistlaunchctl kickstart gui/$(id -u)/com.sim1222.ci-colimaこれで、LaunchAgentによってColimaがciユーザーのログイン時に自動実行されるようになりました。
Linux Gitea Runner
LinuxのGitea Runnerはdockerコンテナとして起動し、CIごとにコンテナを生やせるようにします。
gitea-runner-linux/compose.yaml
services: runner: image: docker.io/gitea/runner:3 container_name: gitea-runner-linux restart: unless-stopped
environment: CONFIG_FILE: /config.yaml
GITEA_INSTANCE_URL: "${GITEA_INSTANCE_URL}" #GITEA_RUNNER_REGISTRATION_TOKEN: "${GITEA_RUNNER_REGISTRATION_TOKEN}" GITEA_RUNNER_NAME: "m6-linux-arm64" GITEA_RUNNER_LABELS: "linux-arm64:docker://docker.gitea.com/runner-images:ubuntu-latest"
volumes: - runner-data:/data - ./config.yaml:/config.yaml:ro - /var/run/docker.sock:/var/run/docker.sock
ports: - "8088:8088"
volumes: runner-data:.envにはGiteaのインスタンスURLとRunner registration tokenを入れます。
GITEA_INSTANCE_URL=https://gitea.example.com/GITEA_RUNNER_REGISTRATION_TOKEN=xxxxxxxxcache: enabled: true dir: "" host: host.docker.internal port: 8088macOS Runner
brew install openai/tools/tarttart clone ghcr.io/cirruslabs/macos-golden-gate-xcode:latest golden-gate-xcodetart clone golden-gate-xcode macos-runnertart run --no-graphics macos-runnerssh admin@$(tart ip golden-gate-xcode)あとは同様にgitea runnerをhostモードで動作させ、tartをLaunchAgentで自動起動