Jan ServerはJanプロジェクトのうちセルフホストできる側です。OpenAI互換のAPIを公開するGoのマイクロサービス群で、その前段にMCPツール連携、Keycloakによる認証、Kongゲートウェイが並びます。単一のコンテナではなく、導入手順もそれを反映しています。
さいわい、プロジェクトは設定を書き起こしてくれるセットアップウィザードを同梱しています。その途中で下す主な判断は、推論をどこで動かすかです。
始める前に
- 8 GB以上のRAMを備えたVPS——プロジェクトが明記する最小要件で、サービス一式には12 GBが推奨されています
- クリーンなLinux環境(Ubuntu 24.04 LTSが無難な既定です)
- Docker EngineとDocker Compose v2
makeとgit- TLSが必要ならドメイン名。検証以外の用途ならまず必要になります
安価なVPSプランの多くは4 GBで、これでは足りません。下限を満たすのは次のとおりです。
| プロバイダー | プラン | vCPU / RAM / ディスク | 価格 | リンク |
|---|---|---|---|---|
| Contabo | Cloud VPS 4 | 4 / 8 GB / 100 GB | 税抜 5.50 EUR/月 | Contabo |
| Hetzner Cloud | CX33 | 4 / 8 GB / 80 GB NVMe | 税抜 8.49 EUR/月 | Hetzner Cloud |
| DigitalOcean | 8 GBのDropletティア | 8 GB | 最新の価格を確認 | DigitalOcean |
| Vultr | 8 GBのインスタンスティア | 8 GB | 最新の価格を確認 | Vultr |
| Linode | 8 GBの共有ティア | 8 GB | 最新の価格を確認 | Linode |
これらのプランの詳しい内訳はVPS比較をご覧ください。
手順1:接続して依存関係を導入する
ssh user@your-vps-ip
sudo apt update && sudo apt upgrade -y
sudo apt install -y docker.io docker-compose-v2 make git
sudo systemctl enable --now docker
入ったのがCompose v2であることを確認してください。Jan Serverのcomposeファイルは、v1が解釈できないinclude:キーを使っています。
docker compose version
手順2:リポジトリをクローンする
セルフホスト型アプリの多くとは違い、ここでは自分でdocker-compose.ymlを書きません。リポジトリのcomposeファイルが、インフラ、APIサービス、MCPツール、Webアプリ、推論の各断片を読み込みます。
git clone https://github.com/janhq/server.git
cd server
手順3:セットアップウィザードを実行する
make quickstart
ウィザードはルートに1つの.envを書き出し、続けてComposeを起動します。尋ねられるのは3点です。
- LLMプロバイダー:モデルをダウンロードしGPUを前提とするローカルvLLMか、どちらも不要なリモートのOpenAI互換エンドポイントか。標準的なVPSではリモートのエンドポイントを選んでください。
- MCPの検索プロバイダー:SerperはAPIキーが要り、SearXNGはキーなしでローカルに動きます。検索を無効にしたうえでMCPツールのサービスだけ残すこともできます。
- Media API:アップロードを使うなら有効に、実行時を最小にしたいなら無効のままにします。
ウィザードを対話的に実行できない場合は、テンプレートをコピーして書き込んでください。
cp .env.template .env
nano .env
make setup
make setupは依存関係を確認し、ディレクトリを作成し、何も起動せずにベースイメージを取得します。
手順4:スタックを起動する
make up-full
コンテナが落ち着くと、次の構成になります。
| サービス | ポート | 役割 |
|---|---|---|
| APIゲートウェイ(Kong) | 8000 | すべての入口 |
| LLM API | 8080 | OpenAI互換のチャット補完 |
| Response API | 8082 | 複数ステップのツールのオーケストレーション |
| Media API | 8285 | アップロードとメディアID |
| MCPツール | 8091 | 検索、スクレイピング、コード実行 |
| Webチャット | 3001 | ブラウザのクライアント |
| Keycloak | 8085 | 認証コンソール |
APIのドキュメントはhttp://your-vps-ip:8000/api/swagger/index.htmlで提供されます。
手順5:公開する前に固める
ここは飛ばしてはいけない手順です。公開サーバーでは2つの既定値が危険です。
- Keycloakのコンソールは
admin/adminで出荷されます。 8085番ポートですぐに変更してください。KongはKeycloakが発行したトークンを検証するため、この1つの認証情報がAPI全体を守っています。 - 外部から到達できるのは8000番だけにします。 JWTとAPIキーの検証を行うのはKongで、その背後のサービスのポートは検証しません。残りはlocalhostにバインドするか、ファイアウォールで遮断してください。
sudo ufw allow OpenSSH
sudo ufw allow 443/tcp
sudo ufw enable
そのうえでCaddy、Traefik、NginxのいずれかでTLSを終端し、8000番へプロキシします。認証のないLLMエンドポイントを公開インターネットに置けば、たいてい数日のうちに見つけられ、他人に使われます。
推論をローカルで動かす場合
ローカルのvLLMを選んだ場合、推論の断片は2つのプロファイルを定義します。GPUプロファイルは既定モデルjanhq/Jan-v1-4Bとともにvllm/vllm-openai:v0.11.2を実行し、NVIDIAデバイスを確保するため、一般的なVPSでは起動しません。CPUプロファイルはGPUなしで動き、検証には実用的ですが、共有vCPUでのトークン生成は利用者の前に出したくない程度の速度です。
GPUの計算資源を借りてJan Serverからリモートのエンドポイントとして呼ぶほうが、プロンプトの合間に遊んでいるGPUサーバーを持つより安く済むのが普通です。
日々の運用
新しいリリースへ更新するには次を実行します。
git pull
docker compose pull
make up-full
Postgresのボリュームと、ルートの.envをバックアップしてください。.envにはウィザードが生成したシークレットが入っており、これなしでデータベースだけを復元すると、復号できないセッションが手元に残ります。
各サービスの様子はdocker compose logs -f llm-apiのように、見たいサービス名を指定して確認できます。
よくあるトラブル
| 症状 | 原因 |
|---|---|
includeは有効なcomposeのキーではないと言われる | Docker Compose v1が入っている。v2が必要です |
| 起動中にコンテナが落とされる | RAMが8 GB未満で、スタックがOOMで停止させられている |
| すべてのAPI呼び出しが401を返す | リクエストが8000番のKongではなく、サービスのポートへ直接届いている |
| vLLMのコンテナがいつまでも正常にならない | NVIDIAデバイスのないホストでGPUプロファイルが有効になっている |
Jan Serverは一般的なセルフホスト型アプリよりVPSに多くを求めます。主な理由は、ゲートウェイ、IDプロバイダー、データベースを手元にある前提とせず、自前で持ち込むからです。8 GBを基準に見積もり、KongをTLSの背後に置き、何よりも先にKeycloakのパスワードを変更してください。
Frequently asked questions
VPSでJan ServerをセルフホストするのにGPUは必要ですか?
セットアップウィザードがLLMプロバイダーを尋ねたときにリモートのOpenAI互換エンドポイントを選べば不要です。その場合VPSはAPI、オーケストレーション、認証のサービスだけを動かします。ローカルvLLMの選択肢にはNVIDIAカードを前提とするGPUプロファイルと、カードなしで動くものの速度が大きく落ちるCPUプロファイルがあります。
Keycloakのコンソールがユーザー名もパスワードもadminで通るのはなぜですか?
composeの構成が同梱している既定の認証情報だからです。手元のマシンなら問題ありませんが、公開サーバーでは通用しません。インターネットにポートを開ける前に変更してください。Kongゲートウェイの背後にあるすべてのAPI経路を守っているのがKeycloakのレルムだからです。
リバースプロキシの背後に置くべきポートはどれですか?
APIゲートウェイであるKongの8000番ポートです。文書化された入口であり、個々のサービスの手前でJWTとAPIキーの検証を行います。サービスのポートを直接公開すると、呼び出し側がゲートウェイと認証をまるごと迂回できてしまいます。