Docker とコンテナ
ZeroClaw を Docker、Podman、Kubernetes、または任意の OCI ランタイムで実行します。
公式イメージ
GitHub Container Registry(ghcr.io)に安定版リリースのたびにプッシュされます:
ghcr.io/zeroclaw-labs/zeroclaw:latest: 最新の安定版ghcr.io/zeroclaw-labs/zeroclaw:v0.7.5: 固定済みghcr.io/zeroclaw-labs/zeroclaw:debian: Debian ベースのイメージ(サイズは大きいが、より広範な glibc サポート)
マルチアーキテクチャ: linux/amd64, linux/arm64。
シェルアクセスに関する注意: デフォルトの
latestイメージは意図的に distroless であり、sh、ash、bashを含んでいません。コンテナ内でシェルが必要な場合(例えば、デバッグのためにdocker execを実行する場合)は、debianタグを使用してください。
Alpine イメージ(ローカルビルド)
Dockerfile.alpine は、linux/amd64 および linux/arm64 向けに静的リンクされた musl バイナリを含む、オプトインの Alpine イメージをビルドします。ghcr.io には公開されません。
ローカルプラットフォームの場合:
sh
docker build -f Dockerfile.alpine -t zeroclaw:alpine .
マルチプラットフォームのレジストリイメージの場合は、ビルダーを一度作成してマニフェストをプッシュします。すでに buildx ビルダーが選択されている場合は、最初のコマンドを省略します:
sh
docker buildx create --use --name zeroclaw-multiarch
docker buildx build -f Dockerfile.alpine \
--platform linux/amd64,linux/arm64 \
-t registry.example.com/zeroclaw:alpine \
--push .
同梱された Compose の例では、現在のプラットフォーム向けのイメージがビルドされます。
sh
docker compose -f docker-compose.yml -f docker-compose.alpine.yml up --build
Alpine イメージは、既存のイメージと同じ /zeroclaw-data マウント、schema-mirror 環境変数、ダッシュボードパス、ゲートウェイポートを使用します。
最小実行
sh
docker run -d \
--name zeroclaw \
-v zeroclaw-data:/zeroclaw-data \
-p 42617:42617 \
ghcr.io/zeroclaw-labs/zeroclaw:latest
公式イメージのデフォルト設定には、[::] へのバインドと allow_public_bind = true、require_pairing = false があらかじめ組み込まれているため、この直接実行用の docker run の例は最初から到達可能です。以下の Compose の例では、永続化された設定やカスタム設定によってループバック専用リスナーが気付かないうちに復元されないよう、ゲートウェイの両方のバインド設定も固定しています。
このイメージは /zeroclaw-data に永続的な状態が存在することを想定しています。初回起動時にはデフォルト設定をブートストラップしますが、実際に使用するにはまだ quickstart を実行する必要があります。
sh
docker exec -it zeroclaw zeroclaw quickstart
zerocode(TUI)の実行
このイメージには、zeroclaw バイナリとともに zerocode ターミナルインターフェースが搭載されています。デフォルトのエントリーポイントは zeroclaw なので、--entrypoint zerocode とインタラクティブ TTY(-it)を指定して zerocode を起動します。公開されている両方のイメージバリアントに含まれています:
distroless (:latest)
docker run -it --entrypoint zerocode ghcr.io/zeroclaw-labs/zeroclaw:latest
debian
docker run -it --entrypoint zerocode ghcr.io/zeroclaw-labs/zeroclaw:debian
zerocode は実行中の ZeroClaw デーモンに接続するため、それを指定してください:
- 同一コンテナのデーモン: すでにデーモンを実行しているコンテナに対して実行します(
docker exec -it zeroclaw zerocode)。これはローカルの IPC ソケット経由でデーモンに到達します。 - リモートデーモン: WebSocket Secure 経由で
zerocode --connect wss://<host>:<port>を使って接続します。リモートセットアップ (WSS) を参照してください。これは、コンテナ化されたデーモンやリモートデーモンを自分のターミナルから操作するためのポータブルな方法です。
/zeroclaw-dataを永続化して(Minimum runと同様に)、zerocodeが読み取る設定とアイデンティティがデーモンの使用するものと同じになるようにします。
作成
最小限の docker-compose.yml:
サービス:
ゼロクロー:
画像: ghcr.io/zeroclaw-labs/zeroclaw:latest
再起動: unless-stopped
ポート:
- "127.0.0.1:42617:42617" # ゲートウェイ、ホストのループバックのみ
volumes:
- ./data:/zeroclaw-data
環境:
# host はコンテナインターフェイスを選択します。allow_public_bind は
# 非ループバックリスナーを認識し、起動時の警告を抑制します。
- ZEROCLAW_gateway__host=0.0.0.0
- ZEROCLAW_gateway__allow_public_bind=true
コンテナの起動後、quickstart を実行します:
sh
docker compose exec zeroclaw zeroclaw quickstart
Compose では ZEROCLAW_gateway__host と ZEROCLAW_gateway__allow_public_bind の両方を明示的に設定する必要があります。ポートを公開しても、コンテナ内で 127.0.0.1 にバインドされたゲートウェイに到達できるようにはならず、allow_public_bind = true はパブリックバインドを許可するだけで、具体的なバインド先は選択しません。2つのオーバーライドを一緒に保持することで、localhost をデフォルトとする既存のボリュームやカスタム設定でも、一貫して動作するようになります。
これは公開範囲を変更するため、例ではホストのループバックに公開します。2つの異なる境界が関係しており、そのうち1つだけが適用されます:
gateway.host = 0.0.0.0はコンテナ内のインターフェースを選択します。Docker ブリッジのトラフィックはコンテナのループバック経由では到達しないため、公開ポートからゲートウェイに到達できるようにするには、これを0.0.0.0のままにしておく必要があります。ZEROCLAW_gateway__allow_public_bindは許可ゲートではなく、確認応答です。falseの場合、ゲートウェイは起動時に警告をログに記録したうえで、バインドします。trueに設定しても、その警告が表示されなくなるだけです。リスナーをプライベートに保つために、これを頼りにしないでください。- Compose の
ports:マッピングが、Docker が実際に適用する境界です。"127.0.0.1:42617:42617"はコンテナーのホストにのみ公開し、"42617:42617"は Docker が構成されているすべてのホストインターフェースで公開します。
認証境界は ZEROCLAW_gateway__require_pairing です。スキーマではデフォルトで true ですが、イメージに焼き込まれた設定では false です。ペアリングを無効にすると、ゲートウェイは /webhook、/api/config、/api/memory、/api/browse、およびセッションエンドポイントへの未認証リクエストに応答します。他のホストにサービスを提供するには、127.0.0.1: プレフィックスを削除し、ペアリングを有効にするか、ゲートウェイを認証機能付きのリバースプロキシまたはトンネルの背後に配置します。
Debian イメージを使用したルートレス Compose
ルートレスのDocker、またはコンテナ内でシェルツールを必要とするPodman Composeデプロイメントの場合は、現在のDebianイメージを使用し、ホストのデータディレクトリをバインドしてください:
サービス:
ゼロクロー:
画像: ghcr.io/zeroclaw-labs/zeroclaw:debian
container_name: ゼロクロー
再起動: unless-stopped
ポート:
- 127.0.0.1:42617:42617
ボリューム:
- ./data:/zeroclaw-data
環境:
- ZEROCLAW_gateway__host=0.0.0.0
- ZEROCLAW_gateway__allow_public_bind=true
healthcheck:
test: [CMD, zeroclaw, 「status」, --format=exit-code]
間隔: 60秒
タイムアウト: 10秒
リトライ: 3
start_period: 10秒
現在の Debian イメージでは、パッケージ化されたダッシュボードが /zeroclaw-data の外部に配置されるため、バインドマウントによって隠されることはなく、gateway.web_dist_dir の上書きも不要です。ゲートウェイの上書きには、ZEROCLAW_gateway__host と ZEROCLAW_gateway__allow_public_bind に示されているスキーマミラーの表記を使用します。これらは永続化された localhost デフォルト設定よりも優先され、ループバックに限定された ports: マッピングが、ホスト側からの到達範囲を制限する境界として機能します。
macOS: OrbStack と Colima の比較
macOS にはネイティブの Linux カーネルが存在しないため、いずれの選択肢(Docker Desktop、Podman、OrbStack、Colima)も軽量な Linux VM 内でコンテナを実行します。Mac の開発環境では、比較する価値のある2つの mac ネイティブ VM は OrbStack と Colima であり、どちらも上記と同じ docker run/Compose コマンドでコンテナを実行します。
| OrbStack | Colima | |
|---|---|---|
| エンジン | カスタムにチューニングされたLinux VM(Apple Silicon最適化済み) | Lima VM + containerd/Docker |
| ライセンス | 商用、フリーミアム(個人利用は無料) | MIT(その下層にある Lima は Apache 2.0) |
| インターフェース | GUIアプリ + CLI | CLI ファースト(colima start/stop)、スクリプト化可能 |
| 適用される場面 | 最小限の手間で洗練されたUX | すべてOSS、設定はコードで管理 |
OrbStack
# docker CLI を提供します:
brew install --cask orbstack
Colima
# docker CLI が colima の VM と通信します:
brew install colima docker docker-compose # docker-compose = Compose v2 プラグイン。`docker compose` が必要な場合はインストールしてください
colima start --cpu 4 --memory 8 # --network-address を追加して、VM の IP を macOS に公開する
パフォーマンスは一般的な開発ワークロードでは同等です。実際の差別化要因は、ライセンス(商用 vs OSS)と UX の好みであり、純粋な速度ではありません。アイドル時の RAM やビルドのスループットが重要な場合は、ご自身のマシンで両方をベンチマークしてください。いずれの場合も、VM 内のエンジンは docker で操作します。systemd quadlet(後述)は Linux ホストの機能であり、macOS には適用されません。
Podman と systemd quadlets
Linux サーバーでは、コンテナを長期的に実行する最もクリーンな方法は Podman の quadlet です。これは systemd が実際のサービスに変換する宣言的なユニットファイルです。systemctl によるライフサイクル管理、journald ログ、自動再起動、ブート順序の制御が、デーモンや --restart のハックなしで利用でき、ユニットファイルは git にコミットできる設定です。これがサーバーで推奨されるパターンです。docker run/Compose はノートパソコンには適しています。
quadlet とは *.container ファイル(同類: .pod、.volume、.network、.kube、.build、.image)のことです。Podman の systemd ジェネレーターは daemon-reload のたびにこれを読み込み、一時的な .service を書き出します。.service を自分で記述することはありません。
ルートフルユニットは /etc/containers/systemd/ に、ルートレスは ~/.config/containers/systemd/ に配置されます。
/etc/containers/systemd/zeroclaw.container:
[Unit]
Description=ZeroClaw agent runtime
After=network-online.target
Wants=network-online.target
[Container]
# Pin a release in production; :latest is distroless (no shell — use :debian to exec a shell).
Image=ghcr.io/zeroclaw-labs/zeroclaw:latest
ContainerName=zeroclaw
PublishPort=127.0.0.1:42617:42617
Volume=zeroclaw-data:/zeroclaw-data
# Published on host loopback only; drop the 127.0.0.1: prefix to serve other
# hosts, and enable pairing or a tunnel before you do. If you mount a
# localhost-default config, override both gateway.host and
# gateway.allow_public_bind together.
# Optional rolling-upgrade path — re-pull a newer image on (re)start and opt into `podman auto-update`:
Pull=newer
AutoUpdate=registry
[Service]
Restart=always
[Install]
WantedBy=multi-user.target default.target
デプロイ(冪等であり、再実行しても安全です。再適用すると実行中のコンテナが収束し、決して重複することはありません):
sh
sudo cp zeroclaw.container /etc/containers/systemd/
sudo systemctl daemon-reload # ジェネレーターが .container を zeroclaw.service に変換します
sudo systemctl restart zeroclaw
その後、一度オンボーディングすれば、他のサービスと同様に管理できます。
sh
sudo podman exec -it zeroclaw zeroclaw quickstart
systemctl status zeroclaw
journalctl -u zeroclaw -f
生成されたユニットには systemctl enable の手順はありません。[Install] WantedBy= の行が、起動時の自動起動を実現します。
- バージョンの固定 vs
:latest。 再現可能で監査可能なデプロイのために、タグまたはダイジェストを固定します(Image=ghcr.io/zeroclaw-labs/zeroclaw:v0.7.5または...@sha256:...)。アップグレードは、コミットされた.containerファイル内のレビュー可能なタグの更新となります。代わりにPull=newer+AutoUpdate=registryを使うと、podman-auto-update.timer(sudo systemctl enable --now podman-auto-update.timer)によって駆動されるローリングアップグレードが得られます。再現性か最新性のどちらかを選択してください。デプロイのループはどちらの場合も同じです。 - Rootless バリアント。 ファイルを
~/.config/containers/systemd/に配置し、systemctl --user daemon-reload && systemctl --user restart zeroclawを使用して、ログアウト後も維持されるようにloginctl enable-linger $USERを実行します(Service & daemon と同じ lingering に関する注記)。 - WSL2。 最新の WSL2 は systemd を実行します(
/etc/wsl.confに[boot] systemd=trueを設定し、wsl --shutdownを実行)。そのため、この quadlet パターンがそのまま WSL ディストリビューション内で動作します。Windows 固有の方言はありません。
コンテナ内の設定
イメージは /zeroclaw-data/.zeroclaw/ 配下に設定があることを想定しています。ローカルの設定を次の場所にマウントしてください:
sh
docker run -d --name zeroclaw \
-v $(pwd)/my-config.toml:/zeroclaw-data/.zeroclaw/config.toml:ro \
-v zeroclaw-state:/zeroclaw-data/workspace \
-p 42617:42617 \
ghcr.io/zeroclaw-labs/zeroclaw:latest
コンテナワークロードの場合は、各 providers.models.<type>.<alias> の uri をコンテナから到達可能なアドレス(例: Docker Desktop ホスト上の Ollama サーバーであれば http://host.docker.internal:11434)に設定してください。汎用の環境変数オーバーライド機構を使えば、設定を編集せずに実行時に同じフィールドを設定できます:
sh
ZEROCLAW_providers__models__ollama__home__uri=http://ollama:11434 zeroclaw agent -a assistant
文法については、プロバイダー → コンテナ対応のオーバーライドを参照してください。
ポーリングを行うチャネル(Telegram、メール):そのまま動作します
アウトバウンド起点のチャネルには、特別なコンテナ設定は必要ありません。Telegram ポーリング、IMAP、MQTT、Nostr リレーはすべてプル型であり、コンテナにはアウトバウンド通信(エグレス)のみが必要です。
Webhookを受信するチャネル: ingressが必要です
Discord、Slack、GitHub、およびほとんどのWebhookチャネルでは、受信HTTPが必要です。2つのオプションがあります:
- ゲートウェイの公開:
-p 42617:42617+ 前段にTLS対応のリバースプロキシを配置し、WebhookのURLをパブリックアドレスに向ける - トンネルを使用する: ngrok、Cloudflare Tunnel、または Tailscale Funnel を使用し、トンネルの URL を Webhook のターゲットとして設定します
[tunnel] の最上位の tunnel_provider(オーバーライド環境変数: ZEROCLAW_tunnel__tunnel_provider)をサポートされているプロバイダーのいずれかに設定し、対応する tunnel.* ブロックを記入することでトンネルを設定します。プロバイダーの完全な一覧とプロバイダーごとのフィールドは Config reference を参照してください。生成された公開 URL が、Webhook の送信元として指定する宛先となります。
Kubernetes
サンプルのKubernetesマニフェストはdeploy-k8s/ディレクトリに用意されています。代表的なマニフェストの断片:
apiVersion: apps/v1
種類: デプロイ
メタデータ:
名前: ゼロクロー
仕様:
レプリカ: 1
戦略:
型: Recreate # ZeroClaw はワークスペースごとに単一インスタンス
template:
仕様:
コンテナ:
- 名前: ゼロクロー
画像: ghcr.io/zeroclaw-labs/zeroclaw:v0.7.5
ポート:
- コンテナポート: 42617
volumeMounts:
- 名前: データ
マウントパス: /zeroclaw-data
# `containerPort` はホストに公開されません。ここでの公開は Service または Ingress
# が制御します。localhost をデフォルトとする設定をマウントする場合は、
# gateway.host と gateway.allow_public_bind の両方を同時に上書きしてください。
volumes:
- 名前: データ
persistentVolumeClaim:
claimName: zeroclaw-data
スケーリング: ZeroClaw はワークスペースごとに単一ライターです。水平スケーリングは行わず、エージェントごとに 1 つのインスタンスを実行してください。
ログアウト後の再認証
コンテナ内で実行中にweb UIからログアウトすると、既存のpaircodeは無効になります。再度ログインするには、新しいものを生成してください:
sh
docker exec -it zeroclaw zeroclaw gateway get-paircode --new
Compose デプロイメントの場合は、代わりに docker compose exec を使用します:
sh
docker compose exec zeroclaw zeroclaw gateway get-paircode --new
注意点
- macOS のホスト名に関する注意点(Docker Desktop、colima、Rancher Desktop)。 macOS 版 Docker Desktop では
host.docker.internalは設定なしで動作します。colima では、colima start --network-addressでインストールした場合にのみ到達可能です(そうでない場合、コンテナはホストをまったく認識できません。VM のゲートウェイ IP(通常は192.168.5.2)経由で接続するか、共有ネットワーク経由でトンネリングしてください)。Rancher Desktop は最近のバージョンでは Docker Desktop と同様の動作をしますが、古いリリースではhost.docker.internalの名前解決失敗が発生していました。プロバイダー呼び出しがhost.docker.internalへのconnection refusedで失敗する場合は、docker run --rm alpine getent hosts host.docker.internalで確認してください。出力が空の場合はホスト名が解決できないことを意味し、明示的な IP を指定する必要があります。 - ホスト側サービス。 プロバイダーがホスト上の Ollama の場合、
uri = "http://host.docker.internal:11434"([providers.models.ollama.<alias>]の下)は Docker Desktop で動作します。Linux Docker では--add-host=host.docker.internal:host-gatewayが必要になる場合があります。 - メモリの永続化。 エージェントのメモリ(SQLite の
brain.db)は、設定ディレクトリ配下の/zeroclaw-data/.zeroclaw/agents/<alias>/workspace/memory/に保存され、共有インスタンスのデータベースは/zeroclaw-data/data/配下に格納されます。/zeroclaw-dataをマウントすればすべてが永続化されます。ボリュームを指定しないと、再起動のたびに会話履歴がすべて失われます。 /zeroclaw-dataのバインドマウントについて。/zeroclaw-dataへのホストバインドマウントは、デフォルト設定や(以前は)ダッシュボードバンドルを含む、イメージディレクトリ全体を置き換えます。ダッシュボードは現在、マウント対象外の/usr/share/zeroclawlabs/web/distにインストールされるため、バインドマウントによって隠されることはなくなりました。初回起動時に空のホストディレクトリをマウントすると、コンテナが新しい設定をブートストラップします。ゲートウェイはイメージパスからダッシュボードを自動検出します。- デフォルトではハードウェアパススルーは行われません。 GPIO / USB には明示的な
--deviceフラグ(--device /dev/ttyUSB0)が必要であり、コンテナのユーザーはdialout/gpioグループに対応する GID を持つ必要があります。
次へ
- サービス管理
- 運用 → ネットワーク展開: トンネル、リバースプロキシ