Compose での本番構成
4 サービス構成の Compose デプロイ — Postgres、オブジェクトストレージ、ワンショットのマイグレーションジョブ、アプリ — に加えて TLS、外部データベース、そして添付アップロードを全滅させる認証情報の落とし穴。
オールインワンイメージは、すべてを 1 つのコンテナのライフサイクルに載せています。試用ではそれが正しい割り切りですが、本番では逆です: データベースを止めずにアプリだけ再起動することができず、各部分を個別にスケール・バックアップ・アップグレードすることもできません。
Compose デプロイはこれを 4 つに分けます:
| サービス | 中身 | 備考 |
|---|---|---|
postgres | Postgres 16 | 専用の named volume |
seaweedfs | 添付ファイル用オブジェクトストレージ | Apache-2.0、S3 互換 |
migrate | ワンショットのマイグレーションジョブ | 完了したら終了 |
app | Busabase 本体 | 上の 3 つを待つ |
マイグレーションを独立サービスにしている理由
migrate は 1 回走って終了し、app はそれに対して condition: service_completed_successfully を宣言しています。これはアプリのレプリカを 2 つ以上動かした瞬間に効いてきます: 各レプリカが起動時にマイグレーションを走らせると互いに競合し、負けた側は「ロック競合」ではなく「スキーマが壊れている」ように見える形で失敗します。
セットアップ
git clone https://github.com/busabase/busabase-premium.git
cd busabase-premium/compose
./init.sh
BUSABASE_IMAGE=busabase/busabase-premium:latest docker compose up -d.env を手で編集せず init.sh を実行してください。S3 の認証情報は2 か所 — アプリ側の .env とストレージ側の seaweed-s3.json — に現れ、両者は一致していなければなりません。手作業で両方書いて片方を書き漏らすのが、ここで最も多い自滅パターンです。しかも症状が紛らわしい: アプリは問題なく起動し、ログインも問題なくでき、そのうえで添付のアップロードだけが毎回失敗します。
init.sh は既存の .env を上書きしません。これは意図的です — すでにデータがあるデータベースに対して認証情報を再生成すると、自分が締め出されます。
TLS とリバースプロキシ
Compose ファイルには TLS を終端するものは含まれていません。アプリのポートの前段にご自分のプロキシを置き、APP_URL をユーザーが実際に入力するアドレスに設定してください:
server {
listen 443 ssl;
server_name busabase.company.internal;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Busabase はエージェント出力をストリーミングし、リアルタイム更新に
# websocket を使います。
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
}
client_max_body_size 100m;
}proxy_buffering off と Upgrade ヘッダーは省略できません。バッファリングが有効だと、エージェントの応答がストリーミングされずターン終了時に一括で届き、「エージェントが固まった」ように見えます。client_max_body_size は最大の添付ファイル以上にしてください。さもないと Busabase に届く前にプロキシでアップロードが弾かれます。
APP_URL は公開アドレスとスキームもポートも含めて完全に一致している必要があります。セッション cookie がこれを基準に発行されるため、食い違うと「ログインは成功したように見えて、すぐログイン画面に戻される」という挙動になります。
自前の Postgres や S3 を使う
Compose 内のこの 2 サービスは利便性のためであり、必須ではありません。すでに運用している基盤を使うには、アプリをそちらに向けてローカルサービスを外します:
PG_DATABASE_URL=postgresql://user:password@your-host:5432/busabase
STORAGE_URL=minio://ACCESS_KEY:SECRET_KEY@your-s3-host:9000/bucket?auto_create=true&ssl=falseストレージは個別の変数群ではなく URL 1 本で設定します。minio:// は「S3、path-style アドレッシング、TLS なし」を意味する内部的なタグで、ベンダーではなくプロトコルを表します。SeaweedFS でも MinIO でも、その他の S3 互換ストレージでも正しく動きます。TLS エンドポイントなら ssl=true にしてポートを外してください。
この変更をする場合は depends_on からも postgres / seaweedfs を外してください。そうしないと Compose は、もう起動しないサービスを永遠に待ち続けます。migrate は残します — どのデータベースを選んでもマイグレーションは必要です。
S3 がヘッダーを書き換えたり削除したりするプロキシの背後にある場合は、トラブルシューティングのチェックサムの項を参照してください。