Melso Docs

セルフホストクイックスタート

Docker Compose で Melso を起動し、ログインして、最初の実行用コンピュータを接続します。

Melso のセルフホストは 2 つの部分に分かれます。

構成要素実行するもの置く場所
Melso サービスWeb、API、PostgreSQLDocker をインストールした 1 台のマシン
実行用コンピュータMelso デーモンと AI コーディングツール開発者が実際に作業するコンピュータ

両者は同じマシンでも、別々のマシンでも構いません。セルフホストで置き換えるのは Melso Cloud の部分だけです。

このページでは Docker Compose を使います。Kubernetes でのデプロイは、リポジトリの Self-hosting guide を参照してください。

始める前に

Melso サービスを実行するマシンには次が必要です。

  • Docker Engine または Docker Desktop(docker compose が実行できること)
  • Git、Make、curl、OpenSSL
  • ポート 30008080 が空いていること

まず Docker と Compose が使えることを確認します。

docker info
docker compose version

Melso は Compose v2(docker compose)を使います。旧版の docker-compose v1 はサポートされません。

実行用コンピュータには、Claude Code、Codex、Cursor などの AI コーディングツールを最低 1 つインストールし、ログインしておく必要があります。Melso CLI はステップ 5 でインストールします。

1. Melso を起動する

サービスを実行するマシンで次を実行します。

git clone --depth 1 https://github.com/albertsalgueda/melso.git
cd multica
make selfhost

初回実行時、make selfhost は次を行います。

  1. .env.example から .env を作成する
  2. JWT_SECRET、PostgreSQL パスワード、MULTICA_VCS_SECRET_KEY(セルフホストの Git 連携用の暗号化キー)をランダム生成する
  3. PostgreSQL、Melso backend、Melso frontend のイメージを取得する
  4. 永続化ボリュームを作成し、3 つのコンテナを起動する
  5. backend がヘルスチェックに応答し始めるまで待機する

2 回目以降の make selfhost は既存の .env とボリュームをそのまま使い、シークレットを再生成しません。

make selfhost は公開済みのイメージを取得し、checkout 中のコードをビルドしません。ローカルのソースを試すには make selfhost-build を使ってください。

2. サービスの準備完了を確認する

コンテナの状態を確認します。

docker compose -f docker-compose.selfhost.yml ps

postgreshealthybackendfrontend が実行中であることを確認します。続いて backend、データベース、migration をチェックします。

curl -fsS http://localhost:8080/readyz

期待されるレスポンスは次のとおりです。

{"status":"ok","checks":{"db":"ok","migrations":"ok"}}

backend コンテナは起動のたびにデータベースの migration を実行してからサービスを開始するため、migration コマンドを手動で実行する必要はありません。

3. アクセス方法を選ぶ

ローカルアクセス

http://localhost:3000 をそのまま開きます。後で melso setup self-host を実行するときも、URL を渡す必要はありません。

リモートアクセス

Docker Compose はデフォルトで 30008080127.0.0.1 だけにバインドします。0.0.0.0 に変えて公開インターネットへ直接さらさず、HTTPS 付きのリバースプロキシを使ってください。

以下では 2 つのドメインを例にします。

  • app.example.com: Melso Web
  • api.example.com: API、ヘルスチェック、デーモン接続

まず .env に公開 URL を設定します。

FRONTEND_ORIGIN=https://app.example.com
MULTICA_APP_URL=https://app.example.com
MULTICA_PUBLIC_URL=https://api.example.com

この構成ではブラウザのトラフィックがすべて app ドメインを経由し、cookie がドメインをまたがないため、COOKIE_DOMAIN の設定は不要です。ブラウザに api ドメインへ直接アクセスさせる場合は設定が必須です。環境変数を参照してください。

次に DNS を設定し、Caddy でローカルポートをプロキシします。

app.example.com {
    # ブラウザの WebSocket は backend へ直接渡す
    @ws path /ws /ws/*
    handle @ws {
        reverse_proxy 127.0.0.1:8080 {
            flush_interval -1
        }
    }

    # 残りのパスは frontend へ。API とログインのリクエストを転送する
    handle {
        reverse_proxy 127.0.0.1:3000
    }
}

api.example.com {
    reverse_proxy 127.0.0.1:8080 {
        flush_interval -1
    }
}

Caddy が TLS 証明書を取得し、WebSocket を転送します。.env を変更したら、up -d でコンテナを作り直して新しい設定を反映します。

docker compose -f docker-compose.selfhost.yml up -d
curl -fsS https://api.example.com/readyz

docker compose restart は既存のコンテナを再起動するだけで、.env を読み直しません。設定を変更した後に .env を読み直すには、docker compose -f docker-compose.selfhost.yml up -d を実行してください。

4. ログインしてワークスペースを作成する

ローカルの http://localhost:3000、または先ほど設定した https://app.example.com を開き、メールアドレスを入力して認証コードをリクエストします。

デフォルトではメールサービスは設定されていません。コードをリクエストしたら、backend のログから読み取ります。

docker compose -f docker-compose.selfhost.yml logs backend \
  | grep "Verification code"

ログには次のような行が出力されます。

[DEV] Verification code for you@example.com: 123456

コードを入力して、最初のワークスペースを作成します。Resend または SMTP を設定すると認証コードはメールで送信され、メンバーがコンテナログを読む必要はなくなります。詳しくはログインとサインアップ設定を参照してください。

セルフホストのデプロイはデフォルトで APP_ENV=production を使い、固定の認証コードは有効になりません。公開インスタンスで MULTICA_DEV_VERIFICATION_CODE を設定しないでください。

5. 実行用コンピュータを接続する

以下のコマンドは AI コーディングツールを実行するコンピュータで実行します。Docker を実行しているサーバーとは限りません。

タスクはデーモンを実行しているユーザーの全権限で動作し、そのユーザーが読み書きできるものはすべて読み書きできます。個人アカウントではなく、専用の Unix ユーザー、コンテナ、または VM でデーモンを実行してください。セキュリティモデルを参照してください。

まず Melso CLI をインストールします。

macOS / Linux

curl -fsSL https://downloads.melso.ai/install.sh | bash

Windows PowerShell

irm https://downloads.melso.ai/install.ps1 | iex

Melso サービスがこのコンピュータでも動いている場合は、次を実行します。

melso setup self-host

Melso サービスが別のマシンで動いている場合は、先ほど設定した 2 つの URL を渡します。

melso setup self-host \
  --server-url https://api.example.com \
  --app-url https://app.example.com

このコマンドはまず <server-url>/health を確認し、次にブラウザを開いてログインを完了します。ログイン後はローカルに認証情報を保存し、デーモンを起動します。

接続状態を確認します。

melso daemon status

正常であれば、出力に次が表示されます。

  • Daemon: running
  • Agents にこのマシンにインストール済みの AI コーディングツールが並ぶ
  • Workspaces0 より大きい

6. 最初の実行を完了する

Melso に戻ります。ランタイム一覧にオンラインのランタイムが表示されたら、エージェントを作成し、最初のイシューを割り当てます。

実行ログが完了になり、タイムラインにエージェントの返信が現れれば、セルフホストのサービス、実行用コンピュータ、AI コーディングツールがつながっています。詳しい手順はクイックスタートのステップ 3〜5 を参照してください。

よく使う管理コマンド

以下のコマンドはすべて multica リポジトリのディレクトリで実行します。

# 状態を確認する
docker compose -f docker-compose.selfhost.yml ps

# backend のログを追う
docker compose -f docker-compose.selfhost.yml logs -f backend

# .env の変更を反映する
docker compose -f docker-compose.selfhost.yml up -d

# サービスを停止する(ボリュームは保持)
docker compose -f docker-compose.selfhost.yml down

公開済みの最新イメージへアップグレードします。

git pull --ff-only
docker compose -f docker-compose.selfhost.yml pull
docker compose -f docker-compose.selfhost.yml up -d
curl -fsS http://localhost:8080/readyz

Docker Compose 構成のアップグレード方法は2通りあります。既存の構成では同じ結果になります — Makefileselfhost ターゲットは同じ docker compose pull + up -d を実行し、加えて .env が無ければ生成し、/health を待ってからステータスの要約を表示します。好きな方を使ってください。

cd multica
git pull
make selfhost
cd multica
git pull
docker compose -f docker-compose.selfhost.yml pull
docker compose -f docker-compose.selfhost.yml up -d

git pull が実際に更新するもの

git pull が更新するのは docker-compose.selfhost.yml そのものです — 新しい環境変数、新しいサービス、変更された healthcheck。新しい Melso のバージョンを取得する仕組みではありません

実際に動くバージョンを決めるのは docker compose pull で、そのタグが今どのイメージを指しているかを GHCR に問い合わせます。したがって数か月更新していない checkout でも今日の latest イメージを取得できますし、逆に git pull だけではイメージを取得してコンテナを作り直すまで何も変わりません。

MULTICA_IMAGE_TAG を固定している場合、どちらのコマンドでもアップグレードされません。 両方のイメージが ${MULTICA_IMAGE_TAG:-latest} として解決され(docker-compose.selfhost.yml:42:125)、.env.exampleMULTICA_IMAGE_TAG=latest を同梱しています。.env で特定のリリースに固定していると、pull は同じタグを取り直すだけで、古いバージョンのままです — エラーも警告も出ません。アップグレード前に確認してください。

grep MULTICA_IMAGE_TAG .env
# MULTICA_IMAGE_TAG=v0.4.5   ← 固定されている: 先に latest(または希望のリリース)へ変更する

.env は上書きされません

make selfhost.env を生成するのは、ファイルが存在しないときだけです。既存の構成で再実行しても、JWT_SECRET、Postgres のパスワード、メール設定、FRONTEND_ORIGIN はそのまま残ります。

先に Postgres をバックアップする

migration は前方向のみで巻き戻せないため、大事な環境をアップグレードする前にダンプを取ってください。

docker compose -f docker-compose.selfhost.yml exec -T postgres \
  pg_dump -U multica multica > multica-backup.sql && gzip multica-backup.sql

pg_dump を直接 gzip にパイプしないでください。 シェルはパイプラインの最後のコマンドの終了ステータスを返すため、pg_dump … | gzip > backup.sql.gz はダンプが失敗しても 0 で終了し、形式としては完全に正当な、中身が空の20バイトのアーカイブが残ります。先にファイルへリダイレクトすれば pg_dump 自身の終了ステータスが効くようになり、&& は実際に成功したダンプだけを圧縮します。

POSTGRES_USER / POSTGRES_DBmultica のデフォルトから変更している場合は、.env の値に置き換えてください。データは multica_pgdata という名前付きボリュームにあり、docker compose down では消えませんが、down -v では消えます。

migration は自動で実行されます

ステップ1と同じく、バックエンドコンテナはトラフィックを受け付ける前に起動時に ./migrate up を実行します(docker/entrypoint.sh)。個別のアップグレードコマンドはありません — 新しいイメージを立ち上げること自体が migration のステップです。様子を見るには:

docker compose -f docker-compose.selfhost.yml logs -f backend

migration は backend の起動時に自動で実行されます。過去データのバックフィルが必要な migration(103 など)も、バックフィルまで自動で完了します。ごくまれに自動バックフィルが refusing to drop legacy daily rollups で失敗することがあります。対処はトラブルシューティングを参照してください。

/health ではなく /readyz で検証する

/healthliveness プローブで、プロセスが生きている限り {"status":"ok"} を返します — migration が失敗していても同じです。/readyzserver/cmd/server/router.go:680/healthz はそのエイリアス)はデータベースと適用済み migration の集合をチェックするため、失敗したアップグレードを捕捉できるのはこちらです。

curl -s localhost:8080/readyz
# {"status":"ok","checks":{"db":"ok","migrations":"ok"}}

HTTP 200 かつ両方のチェックが ok でない場合、新しいバージョンは migration を完了していません。トラフィックを流す前にバックエンドのログを確認してください。

Kubernetes

Helm には独自のアップグレード経路があります。values ファイルで images.backend.tag / images.frontend.tag に目的のリリースを設定し、helm upgrade を実行してください。タグを変えると Pod スペックが変わるため、Kubernetes が新しいイメージを取得して Deployment をロールします — これが確実な経路です。

kubectl -n multica rollout restart はそれ単体ではアップグレードになりません。チャートは pullPolicy: IfNotPresent を同梱しているため(deploy/helm/multica/values.yaml)、そのタグをすでにキャッシュしているノードでは古いイメージが再利用され、restart しても何も変わりません — MULTICA_IMAGE_TAG の固定と同種の落とし穴です。浮動タグでこの方法を使いたい場合は、先に images.backend.pullPolicy / images.frontend.pullPolicyAlways に設定してください。リポジトリの Self-hosting guide を参照してください。

docker compose downpgdatabackend_uploads を保持します。-v を付けると、データベースを含むこれらのボリュームが削除されます。インスタンスを消去するつもりがない限り、docker compose down -v を実行しないでください。

よくある問題

症状まず確認すること
/readyzok を返さないdocker compose -f docker-compose.selfhost.yml logs backend postgres を実行する。
認証コードが届かないコードを一度リクエストし、backend のログで Verification code を探す。
setup self-host が server に到達できないと報告する実行用コンピュータから https://api.example.com/health をリクエストし、DNS、TLS、リバースプロキシがすべて到達可能か確認する。
デーモンが Agents を表示しないAI コーディングツールが PATH にありログイン済みであることを確認し、melso daemon restart を実行する。
イシューがキューにとどまり続けるmelso daemon status を実行し、デーモンが起動していてワークスペースに接続していることを確認する。

その他のケースはトラブルシューティングを参照してください。

次のステップ