Skip to content

設定

設定はすべてリポジトリルートの minato.toml に記述します。このファイルは リポジトリで管理し、すべての worktree が同じ内容を参照します。

キーの一覧は minato.toml リファレンス にあります。 このページでは、各設定の背景にある考え方を説明します。

最小構成

toml
[project]
name = "myapp"

[services.web]
image = "node:22"
port = 3000
command = "npm run dev"

プロジェクト名はすべての URL に含まれるため、1 つの daemon が管理する プロジェクト間で一意である必要があります。同名のプロジェクトを登録しようと した場合は、URL が衝突する前にエラーとなります。

複数のサービス

toml
[services.web]
image = "node:22"
port = 3000
command = "npm run dev"
depends_on = ["api"]

[services.api]
image = "node:22"
port = 8080
command = "npm run api"
depends_on = ["db"]

[services.db]
image = "postgres:16"
port = 5432
scope = "project"
expose = false
volumes = ["pgdata:/var/lib/postgresql/data"]
env = { POSTGRES_PASSWORD = "postgres" }

depends_on は起動順序を指定します。依存先が health 状態になるまで待つわけ ではありませんが、順番に起動し、それぞれに起動時間を確保します。

scope: worktree ごとか、共有か

設定のなかで最も重要な選択です。

toml
scope = "workspace"   # 既定値。worktree ごとに 1 インスタンス
scope = "project"     # 全 worktree で 1 インスタンスを共有

worktree ごとにデータベースを立てると、それぞれに初期データの投入が必要になり、 リソースもその分消費します。共有すればすべてのブランチが同じデータを参照 します。開発中はこちらが適していることが多い一方、ブランチごとに異なる マイグレーションを持つ場合には問題になります。

なお、Minato はマイグレーションの競合を解決しません。共有データベースに対して 互換性のないマイグレーションを適用するブランチが複数あれば、当然衝突します。 そうしたケースでは scope = "workspace" を選び、初期データ投入のコストを 受け入れてください。

公開の制御

toml
expose = false

expose = false を指定したサービスには、URL もルーティングも作成されません。 他のサービスからは内部的にアクセスできますが、環境の外側からは到達できません。 データベースやキャッシュには基本的に指定すべき設定です。

port が設定されている場合の既定値は true です。

ヘルスチェック

toml
health = "http://localhost:3000/healthz"
health = "tcp://localhost:5432"

サービスが「起動した」だけでなく「リクエストを受け付けられる」状態になったか を判定する方法です。指定がない場合の判定は TCP 接続の可否のみとなり、HTTP サービスでは応答可能になるより前に成立してしまいます。

2 点、注意があります。

  • http://使われるのはパスのみです。設定に記述するのはコンテナ内から 見たアドレスですが、Minato が実際に接続するのはランタイムが割り当てた アドレスであるため、ホスト名とポート番号は無視されます。
  • cmd: はコンテナ内で実行されます。health = "cmd:pg_isready -U postgres" のように書きます。接続を受け付ける 状態と、クエリに応答できる状態を区別できるのはこの形式だけです。postgres は 初期化が完了するかなり前から listen を始めます。コマンドはシェルと同様に 分割されますが、シェル自体は介さないため、パイプを使う場合は sh -c で 包んでください。

scale-to-zero によって停止中のサービスが起動する際も、この判定の完了を待ち ます。適切なヘルスチェックを設定しておくと、最初のリクエストの応答が速く、 確実になります。

アイドルタイムアウト

toml
idle_timeout = "30m"

リクエストが来ない状態が続いたとき、自動停止するまでの時間です。既定値は 30 分です。起動に時間がかかるサービスには長めに、worktree を頻繁に作成する 場合は短めに設定してください。

計測の起点はプロキシを経由した最後のリクエストです。コンテナ間の通信は カウントされないため、他のサービスからのみアクセスされるサービスは、呼び出し 元が稼働中でも停止します。そうしたサービスには長めの値を設定するか、 タイムアウトを設けないでください。

ボリューム

toml
volumes = [
  "pgdata:/var/lib/postgresql/data",   # 名前付きボリューム。ランタイムが管理
  "./seed:/seed",                      # ホストのパス。worktree からの相対パス
  "/etc/ssl/certs:/certs:ro",          # 絶対パス、読み取り専用
]

スラッシュを含まない指定は、ランタイムが管理する領域を意味します。この領域は プロジェクト単位のため、worktree 間で共有されます。/./~/ で始まる 指定はホストのパスとして扱われます。

名前付きボリュームの代表的な用途は Node の node_modules です。workspace ごと に /workspace/node_modules へマウントすれば、インストールは初回のみで 済みます。

環境変数

値が小さく秘匿する必要のないものは、ここに記述できます。

toml
[services.web]
env = { NODE_ENV = "development" }

それ以外、つまりマシンや worktree ごとに異なる値や、秘匿すべき値は、層構造を 持つ環境変数として管理してください。環境変数 を 参照してください。

ランタイムの選択

toml
[runtime]
default = "docker"   # または "apple"

プロジェクト単位の設定のため、リポジトリごとに異なるバックエンドを使用できます。 切り替えによる違いは ランタイム を参照してください。

URL の接尾辞

toml
[project]
name = "myapp"
domain = "myapp.localhost"   # 既定値。name から導出される

domain を上書きすると、別のドメイン配下で配信できます。ただし指定した ドメインは 127.0.0.1 に解決される必要があり、.localhost 以外の場合は /etc/resolver の設定を追加してください。

独自イメージをビルドする

image を指定する代わりに、build にコンテキストを指定します。

toml
[services.web]
build = "."
port = 3000
command = "npm run dev"

コンテキストはその worktree から取得するため、Dockerfile を変更したブランチ には、その Dockerfile が示すイメージが渡ります。

イメージには Dockerfile と build_args から算出した fingerprint がタグとして 付きます。そのため、内容が同一の worktree 同士は 1 つのイメージを共有し、 同じイメージが既にある場合はビルドをスキップします。停止中のサービスの起動が 速いままなのは、このスキップによるものです。

fingerprint は Dockerfile が COPY するファイルまでは見ないため、 package.json だけの変更では再ビルドされません。minato up --build で 強制できます。

可能であれば既製イメージを使うほうが有利です。node:22 にソースを マウントするほうがビルドより起動が速く、環境が動くまでの手数も少なくて 済みます。build が必要になるのは、システムパッケージや、既製イメージに 含まれないツールチェーンが要る場合です。

未対応の設定

  • minato.local.toml — worktree ごとの設定上書き。環境変数の層構造で 大半の用途は満たせています。

Released under the MIT License.