Skip to content

インストール ​

mado ML Trackingは、Docker ComposeでWeb、API、PostgreSQL、音声・動画のプレビューを作るpreview workerを起動します。学習や推論のJobを実行するworkerは、GPUのあるworkerホストへ別に導入します。

コンテナ役割
web画面を配信し、/api/をAPIへ中継するnginx。ホストの127.0.0.1:5182で待ち受けます
apiAPI。MLflow 3互換API、自動実行、Artifactの回収もこのプロセスが行います
postgresPostgreSQL 16。データはvolume postgresに保存します
preview長い音声や動画の波形・スペクトログラムを作ります(ffmpeg入り)

必要なもの ​

  • Linuxのサーバー(以下はUbuntuでの例)
  • Docker EngineとDocker Compose v2
  • HTTPSで公開するためのDNS名と、TLSを終端するリバースプロキシ

composeのapiはNODE_ENV=productionで動くため、公開URLはhttps://でないと起動しません。webはホストの127.0.0.1:5182だけで待ち受けるので、前段にTLSを終端するリバースプロキシを置きます。

Dockerがまだ無い場合は、ターミナルで次を実行します。

sh
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker "$USER"

一度ログアウトしてログインし直してから、次のコマンドでバージョンが表示されることを確認します。

sh
docker compose version

1. リポジトリを取得する ​

sh
git clone https://github.com/aida0710/mado-ml-tracking.git
cd mado-ml-tracking

2. .envを作る ​

.env.exampleを元に.envを作ります。.envはシークレットを含むので、所有者だけが読める権限にします。

sh
cp .env.example .env
chmod 600 .env

鍵とパスワードを作ります。次のコマンドを実行し、表示された値をそれぞれ.envへ書きます。値をチャットやチケットに貼らないでください。

sh
openssl rand -hex 24      # MMT_POSTGRES_PASSWORD
openssl rand -base64 32   # MMT_STORAGE_SECRET_KEY
openssl rand -base64 32   # MMT_SESSION_ENCRYPTION_KEY(SSOを使う場合。上とは別の値)

.envで主に設定する変数は次のとおりです。

変数入力する値説明
MMT_POSTGRES_PASSWORD上で作った値PostgreSQLのパスワード。.env.exampleには無いので末尾に足します。composeがこの値でDBの接続先を組み立てます
MMT_PUBLIC_URLhttps://tracking.example.com利用者が開くURL。SSOのcallbackにも使います
MMT_WEB_ORIGINMMT_PUBLIC_URLと同じ値画面のorigin。変更操作のOriginの検証に使います
MMT_STORAGE_SECRET_KEY上で作った値画面から追加するS3保存先のシークレットを、DBで暗号化する鍵
MMT_ARTIFACT_MAX_BYTES既定のまま(200GiB)Artifact 1件の上限
MMT_ALLOW_PRIVATE_ORIGINStrueまたはfalsetrueにすると、LANやVPNのprivate IPのURLからも操作できます

SSO(Authentik)を使う場合は、次も設定します。Authentik側の設定はAuthentikでSSOを参照してください。

変数入力する値の例
OIDC_ISSUER_URLhttps://sso.example.com/application/o/ml-tracking/
OIDC_CLIENT_ID、OIDC_CLIENT_SECRETAuthentikのProviderに表示される値
OIDC_ALLOWED_GROUPSmmt-users,mmt-admins(ログインを許すgroup)
OIDC_ROLE_MAPPING_JSON{"mmt-admins":"admin","mmt-users":"user"}(全体管理者にするgroup)
MMT_SESSION_ENCRYPTION_KEY上で作った値

.env.exampleのMMT_DATABASE_URL、HOST、PORT、ARTIFACT_FILESYSTEM_ROOT、AUTH_MODEは、composeのapiではcompose.ymlの値が優先されます。書き換える必要はありません。変数の一覧は環境変数にあります。

3. 認証方式を選ぶ ​

compose.ymlはapiのAUTH_MODEをoidc(SSOだけ)にしています。初めて導入するときは、緊急用のローカル管理者でもログインできるhybridにしておくと安全です。リポジトリの直下にcompose.override.ymlを作り、AUTH_MODEを上書きします。

yaml
services:
  api:
    environment:
      AUTH_MODE: hybrid
AUTH_MODEログイン方法必要な設定
hybridSSOとローカルアカウントOIDC_*とMMT_SESSION_ENCRYPTION_KEY
oidcSSOだけOIDC_*とMMT_SESSION_ENCRYPTION_KEY
localローカルアカウントだけなし(SSOが無い環境)

docker composeはcompose.override.ymlを自動で読みます。次のコマンドでAUTH_MODEが置き換わっていることを確認します。

sh
docker compose config | grep AUTH_MODE

4. 起動してmigrationを適用する ​

イメージを作り、DBを起動してからmigrationを適用します。migrationはAPIの起動時には走らないので、初回と更新のたびに実行します。

sh
docker compose build
docker compose up -d postgres
docker compose run --rm api npm run db:migrate -w @mmt/api

Migration completeと表示されれば完了です。その前に出る../../.env not found. Continuing without it.は、コンテナの中に.envを置いていないことを示すだけで、問題ありません(設定はcomposeがコンテナへ渡しています)。続けて残りのコンテナを起動します。

sh
docker compose up -d
docker compose ps

STATUSがすべてUpで、postgresには(healthy)が付いていることを確認します。APIの応答は次のコマンドで確かめます。

sh
curl -fsS http://127.0.0.1:5182/api/health

{"status":"ok"}が返れば、Webの中継とAPIの両方が動いています。起動しない場合はdocker compose logs apiを確認します。設定が足りないときは、足りない変数の名前がログに出ます。

5. 初期管理者を作る ​

hybridまたはlocalでは、ローカルアカウントの全体管理者を作ります。ターミナルで次を実行し、ユーザー名とパスワード(12バイト以上)を入力します。パスワードは画面に表示されません。

sh
docker compose exec api npm run bootstrap-admin -w @mmt/api

Admin ready: <ユーザー名> ...と表示されれば作成できています。最初のログインでパスワードの変更を求められます。同じユーザー名でもう一度実行すると、パスワードを置き換えて全体管理者に戻せます。パスワードを忘れたときの復旧にも使います。

oidcだけで運用する場合は、OIDC_ROLE_MAPPING_JSONでadminにしたgroupの人が全体管理者になります。

6. HTTPSで公開する ​

リバースプロキシでMMT_PUBLIC_URLのDNS名を受け、http://127.0.0.1:5182へ転送します。Caddyなら次の設定でTLS証明書の取得と転送ができます。

txt
tracking.example.com {
	reverse_proxy 127.0.0.1:5182
}

ほかのリバースプロキシを使う場合は、次の点を守ります。

  • Hostヘッダーを書き換えない
  • リクエスト本文の上限を設けず、bufferせずに転送する(大きなArtifactのアップロードのため)
  • リクエスト全体のtimeoutを設けず、無通信のtimeoutを120秒程度にする

MLflowのmultipart uploadについて

同梱のwebコンテナのnginxは、X-Forwarded-Protoを自分が受けたscheme(http)で上書きします。前段でTLSを終端すると、MLflow SDKのmultipart upload(既定では500MiB以上のファイル)でpartの送り先がhttp://になります。前段がhttp://をhttps://へリダイレクトする構成では、そのuploadが失敗します。大きなファイルをMLflow SDKから送る場合は、.envにMMT_MLFLOW_MULTIPART_UPLOADS=falseを設定すると、SDKが1回のストリーム転送で送ります。

ブラウザでMMT_PUBLIC_URLを開き、ログイン画面が表示されることを確認します。hybridではSSOのボタンも表示されます。

ユーザー名とパスワードを入力するログイン画面

WebとAPIのURL ​

用途URL
画面https://tracking.example.com/
独自APIhttps://tracking.example.com/api/
Python SDKのMMT_API_URLhttps://tracking.example.com(/apiを付けても同じ)
MLflowのMLFLOW_TRACKING_URIhttps://tracking.example.com/api/mlflow/projects/<ProjectのID>
APIの稼働確認https://tracking.example.com/api/health

MLflowの接続先はProjectごとに分かれます。[プロジェクト設定]の「SDK・MLflow 3から接続」の[MLflow 3]に、そのProjectのURLが表示されます。

ホストのディレクトリをArtifactの保存先に使う ​

composeのapiはコンテナの中で動くので、ホストのディレクトリはそのままでは見えません。既定では、ArtifactはartifactsというDockerのvolumeに保存されます。大きなディスクや共有ストレージ(NFS、Lustreなど)に置きたいときは、compose.filesystem-storage.ymlを使います。MMT_FILESYSTEM_STORAGE_DIRに指定したホストのディレクトリが、apiとpreviewのコンテナの中にも同じパスで見えるようになります。

先にディレクトリを作り、コンテナの実行ユーザー(node、uid 1000)が書けるようにします。作らずに起動すると、Dockerがrootの持ち物として作るため、コンテナから書けません。

sh
sudo mkdir -p /srv/mmt/storage
sudo chown 1000:1000 /srv/mmt/storage

.envに次を足します。compose.override.ymlも使っている場合は、COMPOSE_FILEにそれも並べます(COMPOSE_FILEを指定すると、compose.override.ymlは自動では読まれません)。

sh
COMPOSE_FILE=compose.yml:compose.override.yml:compose.filesystem-storage.yml
MMT_FILESYSTEM_STORAGE_DIR=/srv/mmt/storage

docker compose up -dで反映したら、全体設定 → 全体管理 → [ストレージ]で保存先を追加し、[ルートディレクトリ]にこのディレクトリの下のパス(例: /srv/mmt/storage/artifacts)を指定します(保存先)。

workerを導入する ​

学習・推論・評価のJobを実行するには、GPUのあるworkerホストへworkerを導入します。API serverはworkerホストへSSHしません。workerホスト上でmado-tracking-workerコマンドを使って導入し、systemdで常駐させます。手順はworkerの導入を参照してください。

更新する ​

sh
git pull
docker compose build
docker compose run --rm api npm run db:migrate -w @mmt/api
docker compose up -d

DBとArtifactは同じ時点でバックアップしてください。DBだけを戻しても、重みや音声のファイルは戻りません。

次に読む ​

クイックスタートで、最初のProjectを作ってRunを記録します。