パネル専用ではなく一体型サーバーイメージを選ぶ
MetaCubeXDには、名前がよく似た2つのDockerイメージがあります。ghcr.io/metacubex/metacubexd:latestはコンテナの80番ポートでWebダッシュボードだけを配信するパネル専用イメージです。Mihomoを同梱せず、起動や監視もしないため、別に管理しているMihomoのExternal Controllerへ接続する場合に使います。
この記事で扱うのは一体型のghcr.io/metacubex/metacubexd-server:latestです。このサーバーイメージには、ダッシュボード、同一オリジンの制御エージェント、使用するCPUアーキテクチャに合ったMihomoコアが含まれます。プロファイルの管理と検証、Mihomoコアの起動・停止までを1つのサービスで扱えるのが、ここで使う公式Compose構成です。
イメージ名を置き換えないでください:metacubexd-serverをmetacubexdに変えると、画面は開いても同梱のMihomoコアと制御エージェントは利用できません。パネル専用コンテナが正常でも、Mihomoコアが動作している証明にはなりません。
公式Composeの初期構成はプロキシ専用です。明示的に設定したアプリがMixedポートを利用する構成であり、ホストをLAN向け透過ゲートウェイに変えたり、TUNを自動的に有効化したりはしません。
公式Composeを取得し、用途の異なる2つの認証情報を用意する
専用ディレクトリを作成し、MetaCubeXD公式リポジトリからComposeファイルを取得します。同じ場所にローカルの.envを置きます。この記事の公開後にリポジトリの内容やlatestの参照先が変わる可能性があるため、起動前に取得したYAMLを確認してください。
Shellmkdir metacubexd-server
cd metacubexd-server
curl -fLO https://raw.githubusercontent.com/MetaCubeX/metacubexd/main/docs/docker-compose.yml
公式ファイルではCONTROL_TOKENとCLASH_SECRETが必須です。互いに異なる、十分に強いランダム値を.envへ記録してください。サブスクリプションのトークンやアカウントのパスワード、Web上のサンプルに載っている値は流用しません。
.envCONTROL_TOKEN=replace-with-a-unique-control-token
CLASH_SECRET=replace-with-a-different-clash-secret
TZ=Asia/Shanghai
| 変数 | 保護する対象 | 注意点 |
|---|---|---|
CONTROL_TOKEN | /api/control配下の制御エージェントAPI | 同一オリジンの画面へ渡されるため、ダッシュボード自体のログイン機能ではない |
CLASH_SECRET | 9090番のMihomo Clash API | ダッシュボードのEndpointにあるSecretへ入力する |
.envを公開リポジトリ、スクリーンショット、問い合わせ資料、シェル履歴へ残さないでください。これらの値が漏れると、ホストへ接続できる第三者にプロファイルやMihomo APIを操作されるおそれがあります。
検証、取得、起動、状態確認を順番に実行する
docker-compose.ymlと.envがあるディレクトリで実行します。まずCompose設定と必須変数を検証します。認証情報を画面に表示させないよう--quietを付け、その後にイメージの取得、バックグラウンド起動、状態確認、ログ確認へ進みます。
Shelldocker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 metacubexd
config --quietが成功し、必須変数の不足がないことを確認します。pullで現在のComposeが参照するイメージを取得します。up -dでサービスを作成または更新します。psでコンテナとヘルスチェックの推移を確認します。logsで制御エージェント、Mihomoコア、プロファイル、ポート競合に関する最初のエラーを読みます。
公式ファイルのサービス名はmetacubexdで、イメージ名のmetacubexd-serverとは異なります。docker compose logsにはサービス名を指定します。失敗時に何度も作り直す前に、最初の具体的なエラーを保存してください。
3つのポートと書き込み可能なデータボリュームを区別する
公式Composeは3つのTCPポートを公開し、名前付きボリュームを/dataへマウントします。8080はブラウザ画面とエージェント、9090は画面から直接接続するMihomo API、7890はアプリが利用するHTTP/SOCKS Mixedプロキシです。
| ホスト側ポート | 役割 | 確認方法 |
|---|---|---|
8080 | ダッシュボードUIと制御エージェントAPI | http://<host>:8080を開く |
9090 | Mihomo Clash APIとWebSocket | UI Endpointにhttp://<host>:9090を指定 |
7890 | Mihomo Mixed HTTP/SOCKSプロキシ | 許可したクライアントに<host>:7890を設定 |
metacubexd-dataは/dataに接続され、プロファイル、有効な設定、Geoデータ、Mihomoコアのダウンロードデータ、実行時キャッシュを保持します。この場所には書き込み権限が必要です。読み取り専用にすると、同梱のMihomoコアがエラー終了することがあります。
Dockerのポート公開はMihomoの待受ポリシーを上書きしません。Mihomoのallow-lan既定値はfalseです。bridgeネットワークではMixedポートがコンテナのloopbackにのみ待受するため、7890:7890だけでホストやLANからプロキシへ接続できるようにはなりません。公開したプロキシポートを使う場合は、現在有効なプロファイルでallow-lan: trueを明示し、bind-addressとlan-allowed-ipsを必要な範囲に絞ります。さらにauthentication、Dockerのホスト側binding、ホストのfirewallを組み合わせ、プロファイル切り替え後に再確認します。
左側のホストポートだけを18080:8080に変更した場合、コンテナは8080番で待受しますが、ブラウザとホスト側のhealthリクエストは18080番を使います。9090と7890の左側を変更した場合も、Endpointまたはクライアントに新しいホストポートを設定します。コンテナ内のCONTROL_PORTを変更するなら、mappingの右側とhealthcheck URLも同時に変更してください。
コンテナとデータは別物です:サービスの再作成では名前付きボリュームを維持できますが、ボリュームを削除すれば永続状態も失われます。イメージやプロファイルを変更する前に、このボリュームをバックアップ対象へ含めます。
ダッシュボードを開き、同梱のMihomoコアへ接続する
ブラウザでhttp://<host>:8080を開きます。サーバーはCONTROL_TOKENを同一オリジンのページへ注入し、ダッシュボードが/api/controlを確認できるようにします。ユーザーがこのトークンを貼り付ける欄はありません。ただし、ページへ届く値なので、ダッシュボードへのアクセス制御そのものにはなりません。
MihomoのEndpointでは、URLにhttp://<host>:9090、Secretに.envで設定したCLASH_SECRETと同じ値を入力します。8080はUIとエージェントのポートでありClash APIではありません。Endpointを8080へ向けてもMihomoには接続できません。
8080と9090はポートが違うため、ブラウザ上では別オリジンです。有効なMihomoプロファイルのexternal-controller-corsに、例えばhttp://192.168.1.20:8080のような正確なUIオリジンを許可する必要があります。公開ページからプライベートネットワークのControllerへ接続する場合は、Private Network Access(PNA)も確認し、必要な構成でのみallow-private-network: trueを有効にします。画面だけ開いてバックエンド接続に失敗する場合は、Secretやコンテナを変更する前に開発者ツールでCORSまたはPNAエラーを確認します。
HTTPSのUIにはMixed Contentの制約もあります。HTTPSで読み込んだページから、安全でないhttp://<host>:9090のHTTP/WebSocketへ接続すると、CORSの評価より前にブラウザで拒否されるのが通常です。9090番をHTTPS/WSS対応のリバースプロキシの後ろに置くか、Mihomoのexternal-controller-tlsと有効な証明書を設定し、UI Endpointに対応するhttps:// URLを入力します。TLSとMixed Contentを解決した後に、CORSとPNAを確認します。
層ごとに確認:8080の画面、制御エージェント、9090のEndpointとCLASH_SECRET、最後に7890のMixedプロキシという順番なら、失敗箇所を混同しません。

HTTP 200をUIとエージェントの確認だけに使う
サーバーのヘルスエンドポイントは、CONTROL_PORT上のGET /api/control/healthです。公式Composeでは8080番なので、ホスト上から次のように確認できます。
Shellcurl -i http://127.0.0.1:8080/api/control/health
ホスト側のmappingを18080:8080に変更した場合、ホストからのリクエストは18080番を使います。コンテナ内のCONTROL_PORTを変更した場合は、mappingの右側とComposeのhealthcheck URLも同時に変更します。
HTTP 200はダッシュボードサーバーと制御エージェントが応答していることを示します。Mihomoコアの稼働、プロファイル検証の成功、Endpoint Secretの一致、外向きのプロキシ通信までは保証しません。公式Composeのhealthcheckも同じURLを見るため、healthy表示が確認している範囲も同じです。
docker compose psでコンテナとhealthの状態を確認します。- Mihomoコアの状態表示で、同梱コアがrunningになっているか確認します。
docker compose logs --tail=100 metacubexdで設定や起動エラーを読みます。http://<host>:9090とCLASH_SECRETで接続できるか確認します。- 許可した1台からMixedプロキシを使い、ConnectionまたはRuleログを確認します。
この順番なら、8080が200でも、読み取り専用の/data、不正なYAML、ポート競合などでMihomoコアだけが停止している状態を「デプロイ完了」と誤認せずに済みます。
信頼できるLANの外へ出す前に公開ポートを制限する
8080:8080、9090:9090、7890:7890という記述は、既定でホストの全インターフェースに公開されます。VPSや公開経路があるホストでは、ダッシュボード、Clash API、プロキシポートが意図しないネットワークから到達可能になることがあります。CONTROL_TOKENを強くしても、ページ自体の公開は解決しません。
ホストだけから管理するなら、例えば127.0.0.1:8080:8080のようにホスト側をloopbackへ限定します。信頼するLANで使う場合は、ホストファイアウォールまたはACLで接続元を絞ります。遠隔ブラウザからの管理が必要なら、UIを認証付きTLSリバースプロキシの背後へ置き、9090と7890も別々に保護してください。UIのリバースプロキシが他の2ポートまで自動的に保護するわけではありません。
CLASH_SECRETはExternal Controllerを保護し、MihomoのauthenticationはHTTP、SOCKS、Mixedプロキシの利用者認証に使えます。どちらもネットワーク制限の代わりではなく補完です。認証なしのMixedプロキシや広く許可したControllerをインターネットへ直接公開しません。
実際の到達範囲を確認:Composeのbinding、OSファイアウォール、クラウドのSecurity Group、リバースプロキシ設定を一緒に確認します。ホスト内からのテストだけでは外部公開の有無を判断できません。
ボリュームを残したまま更新し、元の状態へ戻せるようにする
公式例はghcr.io/metacubex/metacubexd-server:latestを使用します。latestは固定バージョンではなく、後日同じComposeから異なるイメージが取得されることがあります。更新前に現在動作中のイメージを記録し、metacubexd-dataをバックアップして、正常に動作していたイメージのdigestも控えておきます。
Shelldocker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 metacubexd
更新後は、UIと制御エージェントのhealth、Mihomoコアの稼働状態、Endpoint接続、プロファイル、1件のプロキシ通信を再確認します。新しいイメージで失敗した場合は、必要に応じてデータを復元し、Composeのimage:を記録済みのdigestへ戻してdocker compose up -dを再実行します。
通常の更新や切り分けにdocker compose down -vを使わないでください。-vは、この構成が永続データに使うmetacubexd-dataを含む名前付きボリュームを削除します。コンテナの再作成とデータ削除は別の操作です。
運用方針を明記:latestは追随しやすく、確認済みdigestは再現とロールバックに向きます。「latest」が永久に同じビルドを示すと考えず、採用した方針と確認日を記録します。
TUNはLinux向けの高度な設定。まず標準構成を確認する
公式Composeはプロキシ専用で起動し、TUNなしでダッシュボード、プロファイル管理、明示的に7890を指定するアプリを利用できます。最初にこの最小構成を検証してから、特権を伴うネットワーク機能を検討します。
公式のLinux向けTUN overrideには、network_mode: host、NET_ADMIN capability、/dev/net/tun:/dev/net/tunのdevice mappingが必要です。有効なMihomoプロファイルにも適切なtun:設定が必要です。host networkを使うとDockerはComposeのports: mappingを無視し、8080、9090、7890はホストのnetwork namespaceで直接bindされます。
| 標準のプロキシ構成 | LinuxでTUNを使う場合 |
|---|---|
ports:で公開 | host networkを使用し、ports mappingは無視される |
NET_ADMINやTUN deviceは不要 | NET_ADMINと/dev/net/tunが必要 |
| アプリが7890を明示的に使用 | 有効なプロファイルがTUNのネットワーク動作を定義 |
これらの権限を追加すると、コンテナがホストのネットワークへ与える影響も大きくなります。ただし、他のLAN端末向けのforwarding、NAT、policy routing、DNS方針、firewall ruleまで自動で設定されるわけではありません。ここでは公式資料に記載されたTUNの必要条件だけを説明し、LAN全体で使うネットワークゲートウェイの構築手順には踏み込みません。
公式情報源とバージョン範囲
- MetaCubeXD 公式 README
- MetaCubeXD 公式 Docker Compose 例
- Mihomo 公式の全般設定
- MetaCubeXD all-in-one Server supervisor ソース
バージョン番号、ファイル名、画面表示は更新で変わる場合があります。作業前にリンク先の公式資料を確認してください。