Dockerのクジラの上にAIアシスタント(clawdbot)のコンテナが積まれたイラスト。Vim、Git、Slack、Gemini、GLMなどの開発ツールとセキュリティ設定、プログラミング環境の統合を表現。

Docker ComposeでAIアシスタント環境を構築する完全ガイド

Docker Composeを使ってAIアシスタント(clawdbot)の環境を構築する方法を解説します。

このセットアップにより、コンテナ内でclawdbotを実行し、Telegram/Slack等のプラットフォームと連携できるようになります。

実装の主な特徴は以下の通りです。

  • Dockerfile: node:22-slimベースのコンテナイメージ(zsh、vim、git、curlを含む)
  • docker-compose.yml: サービス定義とボリューム/ポート設定
  • Makefile: コンテナ操作のショートカットコマンド(login, up, down, model切り替え)
  • entrypoint.sh: socat bridgeとGatewayの自動起動スクリプト
graph LR
    subgraph Host["ホストマシン"]
        DC[Docker Compose]
        Vol[(clawdbot-data)]
    end

    subgraph Container["clawdbotコンテナ"]
        Gateway[Gateway<br/>127.0.0.1:18789]
        Socat[socat bridge<br/>:18790]
        Bot[clawdbot]
    end

    Host -->|51121:51122| Container
    Host -->|18789:18790| Container
    DC -.->|マウント| Vol
    Gateway --> Socat
    Socat --> Bot

    style Container fill:#e1f5fe
    style Gateway fill:#fff3e0
    style Bot fill:#f3e5f5

こんな人におすすめ

  • Docker ComposeでAIアシスタント環境を構築したい方
  • 非rootユーザーでのセキュアなコンテナ実行を検討している方
  • 複数のAIモデルを切り替えて使いたい方
  • zsh環境でのコンテナ開発を希望する方

変更差分

Dockerfile

FROM node:22-slim

# Install git, vim, zsh, and other dependencies
RUN apt-get update && apt-get install -y \
    git \
    vim \
    zsh \
    curl \
    socat \
    jq \
    && rm -rf /var/lib/apt/lists/*

# Create a non-root user (using different UID to avoid conflicts)
# Set zsh as default shell
RUN useradd -m -u 1001 -s /bin/zsh clawdbot

# Install clawdbot globally
RUN npm i -g clawdbot@latest

# Wrap clawdbot so that "gateway stop/start/restart" works without systemd.
# The real entry point is preserved as clawdbot-orig.
RUN mv /usr/local/bin/clawdbot /usr/local/bin/clawdbot-orig
COPY clawdbot-wrapper.sh /usr/local/bin/clawdbot
RUN chmod +x /usr/local/bin/clawdbot

# Copy and set up entrypoint script (must be done as root)
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

# Switch to non-root user
USER clawdbot

# Set working directory
WORKDIR /home/clawdbot

# Create default .zshrc to avoid zsh-newuser-install wizard
RUN touch ~/.zshrc && echo "# Default zsh configuration" >> ~/.zshrc

# Auto-start socat bridges and Gateway on container startup
CMD ["entrypoint.sh"]

docker-compose.yml

services:
  clawdbot:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: clawdbot
    env_file:
      - .env
    environment:
      # AI Model Configuration (default, can be overridden by .env)
      CLAWDBOT_AI_MODEL: glm-4.7
      # Discord Guild Allowlist (comma-separated guild IDs)
      # 実際のサーバーIDを設定してください
      # DISCORD_GUILD_IDS: "YOUR_DISCORD_GUILD_ID"
    ports:
      - "127.0.0.1:51121:51122"   # OAuth: localhost only
      - "127.0.0.1:18789:18790"   # Gateway: localhost only
    volumes:
      - ./clawdbot-data:/home/clawdbot/.clawdbot
    restart: unless-stopped
    stdin_open: true
    tty: true

Makefile

.PHONY: help up down logs login shell restart build clean model-glm model-gemini model-status

help:
	@echo "clawdbot Docker Commands:"
	@echo "  make login   - Login to clawdbot container (zsh shell)"
	@echo "  make shell   - Same as login"
	@echo "  make up      - Start the container"
	@echo "  make down    - Stop the container"
	@echo "  make restart - Restart the container"
	@echo "  make build   - Build the Docker image"
	@echo "  make logs    - View container logs"
	@echo "  make clean   - Remove containers and images"
	@echo ""
	@echo "Model switching (no restart needed):"
	@echo "  make model-glm    - Switch to GLM 4.7"
	@echo "  make model-gemini - Switch to Gemini 3 Flash"
	@echo "  make model-status - Show current model"

login:
	docker compose exec -it clawdbot zsh

shell: login

up:
	docker compose up -d

down:
	docker compose down

restart:
	docker compose restart clawdbot

build:
	docker compose build

logs:
	docker compose logs -f clawdbot

clean:
	docker compose down
	docker rmi your-project-clawdbot:latest

model-glm:
	docker compose exec clawdbot clawdbot models set zai/glm-4.7
	@echo "Switched to GLM 4.7"

model-gemini:
	docker compose exec clawdbot clawdbot models set google-antigravity/gemini-3-flash
	@echo "Switched to Gemini 3 Flash"

model-status:
	docker compose exec clawdbot clawdbot models status

.DEFAULT_GOAL := help

entrypoint.sh(抜粋)

#!/bin/bash
# Container entrypoint: auto-start socat bridges and Gateway on container startup

# Fix state directory permissions (security hardening)
chmod 700 /home/clawdbot/.clawdbot 2>/dev/null || true
chmod 700 /home/clawdbot/.clawdbot/credentials 2>/dev/null || true

# Start socat bridge: container:18790 → 127.0.0.1:18789 (Gateway)
echo "Starting socat bridge for Gateway (18790 → 127.0.0.1:18789)..."
socat TCP-LISTEN:18790,fork,reuseaddr TCP:127.0.0.1:18789 &

# ... (OAuth bridge and Gateway auto-start logic continues)

その他の追加ファイル

  • .env.example: 環境変数テンプレート(API keys, Telegram/Slack設定)
  • .gitignore: .env, clawdbot-data/, IDE設定の除外
  • CLAUDE.md: Claude Codeへのプロジェクトガイド(506行)
  • clawdbot-wrapper.sh: systemdなし環境でのgateway制御ラッパー
  • dcl: コンテナログインショートカットスクリプト

良かった点

このDocker Compose環境で実際に運用してみて、特に良かった点があります。

Makefileのショートカットコマンドが便利

コンテナ操作やモデル切り替えがmake xxxで完結するため、毎回docker composeコマンドを入力する手間が省けます。

特にmake model-glmmake model-geminiでAIモデルを切り替えられるのは、動作確認や性能比較で重宝しました。

再起動なしでモデルを変更できる点も大きいです。コンテナを止めることなく、即座に別のAIモデルを試せます。

非rootユーザー実行の安心感

UID 1001の専用ユーザーで実行することで、ホスト側のユーザー権限と衝突せず、セキュリティ的にも安心です。

ボリュームマウント時のファイル権限問題も回避でき、スムーズに開発を進められました。

zsh環境の快適さ

デフォルトシェルがzshなため、補完機能やエイリアスが使えて操作性が高いです。

vimやgitもプリインストールされているため、コンテナ内で即座に開発作業ができます。

つまづいた点

セットアップ時にいくつかハマったポイントがあります。

socat bridgeの必要性

当初、Gatewayのポート設定で躓きました。

コンテナ内部の127.0.0.1:18789と、コンテナ外部からアクセスするポート:18790を中継するsocat bridgeが必要でした。

この設定がないと、OAuth認証やGateway通信が正しく動作しません。

最初はこの仕組みが理解できず、OAuthコールバックが失敗する原因を特定するのに時間がかかりました。

zsh-newuser-installの回避

非rootユーザーで初めてzshを起動すると、設定ウィザードが表示されます。

コンテナ起動時にこれが出ると自動化の妨げになるため、.zshrcを事前に作成して回避しました。

# Create default .zshrc to avoid zsh-newuser-install wizard
RUN touch ~/.zshrc && echo "# Default zsh configuration" >> ~/.zshrc

この一行がないと、make loginでzshが起動するたびにウィザードが表示されてしまいます。

systemdがない環境でのgateway制御

clawdbotのgateway start/stop/restartコマンドは、通常systemdに依存しています。

Dockerコンテナ内にはsystemdがないため、このままでは動作しません。

そこでclawdbot-wrapper.shというラッパースクリプトを作成し、systemdなしでgatewayを制御できるようにしました。

補足

設計のポイント

  1. 非rootユーザー実行: セキュリティのため、UID 1001のclawdbotユーザーでコンテナ実行
  2. zshをデフォルトシェル: 補完機能とエイリアスサポート
  3. localhostバインディング: ポートを127.0.0.1に制限して外部露出を防止
  4. socat bridge: コンテナ内部(127.0.0.1)とコンテナポート(18790)を中継
  5. モデル切り替え機能: make model-glm等でAIモデルを再起動なしで変更可能

使い方

flowchart TD
    A[開始] --> B[make build<br/>イメージビルド]
    B --> C[make up<br/>コンテナ起動]
    C --> D[make login<br/>ログイン]
    D --> E{操作}
    E -->|モデル切り替え| F[make model-glm/gemini]
    E -->|ログ確認| G[make logs]
    E -->|停止| H[make down]
    F --> E
    G --> E
    H --> I[終了]

    style B fill:#e3f2fd
    style C fill:#e3f2fd
    style F fill:#fff3e0
    style H fill:#ffebee
# ビルドして起動
make build
make up

# コンテナにログイン
make login

# AIモデル切り替え
make model-glm

# ログ確認
make logs

チェックリスト

  • Dockerfileの作成とビルド確認
  • docker-compose.ymlの設定
  • Makefileのショートカットコマンド実装
  • entrypoint.shの自動起動スクリプト
  • 環境変数テンプレート(.env.example)
  • ドキュメント(CLAUDE.md)作成
  • 実際のTelegram/Slack連携テスト
  • cronジョブ設定のテスト
  • 音声文字起こし機能のテスト(OpenAI Whisper)

まとめ

clawdbotのDocker Compose環境を構築しました。

非rootユーザー実行やlocalhostバインディングなど、セキュリティを考慮した設計になっています。

Makefileによるショートカットコマンドで、コンテナ操作やAIモデル切り替えがスムーズに行える点が便利です。

次回は、Telegram/Slack連携とcronジョブ設定のテストを進める予定です。

よくある質問(FAQ)

Docker Composeで非rootユーザーを実行するには?

DockerfileでUSER指令を使用して、非rootユーザーに切り替えます。

UID 1001などの専用ユーザーを作成し、セキュリティを強化できます。

# Create a non-root user
RUN useradd -m -u 1001 -s /bin/zsh clawdbot

# Switch to non-root user
USER clawdbot

socat bridgeとは何ですか?

socat bridgeは、コンテナ内部のネットワーク(127.0.0.1)と、コンテナ外部からアクセスするポートを中継する仕組みです。

OAuth認証やGateway通信など、localhostバインディングが必要なサービスで活用します。

# Start socat bridge: container:18790 → 127.0.0.1:18789 (Gateway)
socat TCP-LISTEN:18790,fork,reuseaddr TCP:127.0.0.1:18789 &

AIモデルを再起動なしで切り替える方法は?

make model-glmmake model-geminiなどのコマンドで、コンテナを再起動せずにAIモデルを切り替えられます。

これはclawdbotの動的モデル切り替え機能を活用しています。

# GLM 4.7に切り替え
make model-glm

# Gemini 3 Flashに切り替え
make model-gemini

# 現在のモデルを確認
make model-status

zsh-newuser-installウィザードを回避するには?

非rootユーザーで初めてzshを起動すると、設定ウィザードが表示されます。

.zshrcを事前に作成することで、このウィザードを回避できます。

# Create default .zshrc to avoid zsh-newuser-install wizard
RUN touch ~/.zshrc && echo "# Default zsh configuration" >> ~/.zshrc

Dockerコンテナでsystemdなしにプロセスを制御するには?

clawdbotのgateway start/stop/restartコマンドは、通常systemdに依存しています。

Dockerコンテナ内にはsystemdがないため、ラッパースクリプトを作成して代替します。

#!/bin/bash
# clawdbot-wrapper.sh: systemdなし環境でのgateway制御ラッパー

参考リンク

本記事の執筆にあたり、以下の公式ドキュメントを参考にしました。

関連記事

Docker環境の構築について、以下の記事も参考にしてください。