Takuto で外部データベースを使う

デフォルトでは、Takuto はデータをローカルの SQLite ファイル(データディレクトリ内の takuto.db)に保存します。マルチユーザー構成や本番運用では、代わりに外部の PostgreSQLMariaDBMySQL データベースに Takuto を向けることができます。

takuto-cli で既存のデータベース container を接続する

Takuto CLI を使っていて、データベースがこのマシン上の container で動いているなら、 手作業での変換は不要です。takuto setup「A database container running on this machine (auto-wire it)」 を選び、ホストから使うときのままの URL — psql や GUI クライアントに 貼り付ける localhost の URL — を入力します:

[database]
connection = "postgres://takuto:<DB_PASSWORD>@localhost:5433/takuto"
local_container = true   # ウィザードが設定 — 起動時に CLI が自動配線する印

以後 takuto start のたびに、CLI は (1) そのポートを公開している実行中の container と その内部ポートを見つけ、(2) 安定したエイリアス takuto_db で Takuto のネットワークに 接続し、(3) container 向けの TAKUTO_DATABASE_CONNECTION…@takuto_db:5432/…)を takuto.env に書き込みます(エンジンが起動時に使用)。あなたは localhost のまま考えればよく、ネットワーク 名前空間の変換は CLI が行います。

唯一の条件: takuto start の前にデータベース container を起動しておくこと。そのポートを 公開しているものがまだ無ければ、CLI は警告を出して文字列をそのままにします — データベースを 起動して takuto start をやり直してください。

リモートまたはホストネイティブのデータベースは別です: ウィザードで remote / host-native を選び、そのまま到達可能な URL を入力してください。

同梱の Compose オーバーレイ

Takuto Core からエンジンを Docker Compose で動かしているなら、サポートされている方法は 同梱のデータベースオーバーレイです。これはデータベースを 正しいネットワーク上 に追加し、 接続文字列をあなたの代わりに注入し、Takuto が起動する前に データベースが healthy に なるのを待ちます — これにより、下記のネットワークの問題も起動時の競合の問題も両方とも 回避できます:

# PostgreSQL
docker compose -f docker-compose.yml -f docker-compose.postgres.yml up -d
# or: make start BACKEND=postgres

# MariaDB / MySQL
docker compose -f docker-compose.yml -f docker-compose.mariadb.yml up -d
# or: make start BACKEND=mariadb

デフォルト値は、環境変数の POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB(または MARIADB_* の相当物)で上書きできます。オーバーレイは TAKUTO_DATABASE_CONNECTION (これが [database].connection を上書きします)を設定するので、文字列を手で編集する必要は なく、初回起動時には SQLite → 外部への一度きりのインポートが実行されます。

手作業で行う(エンジンを直接動かす)

CLI を使わずTakuto Core を自分で動かす場合、自動配線はありません: Takuto container がそのまま到達できる接続文字列を設定します。このページの残りはその場合を扱います — 別途自分で動かしているもの、あるいはすでに別のネットワーク上にあるもの。

何より大事な唯一のルール

config.toml の接続文字列は、Takuto container 自身 が使います。したがって、その文字列 の中のホストは、その container の内側から 到達できなければなりません:

  • ✅ データベースを 別の container として動かしているなら、その container/サービス名内部ポート を使い、両方の container が同じネットワークを共有していることを確かめてください。
  • localhost127.0.0.1使わないでください — Takuto container の内側では、 それはデータベースではなく Takuto 自身を指してしまいます。
  • ホスト側に公開したポート(例: -p 5433:5432 のマッピング)も 使わないでください。 そのポートはホストマシン上にしか存在せず、container ネットワーク上にはありません。

目安: localhost:<published-port> は、ホストマシン から接続するためのもの(psql や GUI クライアント)。<container-name>:<internal-port> は、Takuto のためのものです。

すでにあるデータベース container を再利用する

すでに PostgreSQL(または MariaDB/MySQL)を container で動かしている — 別の Compose プロジェクトのものかもしれません? 作り直す必要はありません。takuto container が実際に使う ネットワーク — つまり dind sidecar のネットワーク — に接続し、安定したエイリアスを付けて、 そのエイリアスから文字列を組み立てます:

# 1. dind sidecar(つまり takuto)が属するネットワークを調べる:
docker inspect takuto-dind | grep -A8 '"Networks"'

# 2. 既存の DB container を、安定したエイリアスでそのネットワークに接続する:
docker network connect --alias takuto_db <ステップ1のネットワー> <あなたの-db-container>

# 3. エイリアス + データベースの内部ポートから文字列を組み立てる。例:
#    postgresql://<user>:<password>@takuto_db:5432/<db>

文字列の host はこのエイリアスtakuto_db)であり、localhost ではありません。ポートは container の内部ポート(5432 / 3306)で、-p で公開したポートではありません。これを [database].connection(ステップ 2)に入れて再起動します。下のステップは、データベースをゼロから 作る場合を扱います。

ステップ 1 — Takuto のネットワーク上でデータベース container を動かす

Takuto の container 群は Docker/Podman のネットワークを共有します(Compose で起動した場合は プロジェクトのデフォルトネットワーク、例: <project>_default)。データベースをその 同じ ネットワーク に載せてください。いちばん簡単なのは、同じ Compose ファイルにデータベースを サービスとして追加して自動的に参加させる方法です。あるいは、単体で動かしてネットワークに アタッチすることもできます。

各エンジンでは、初回起動時にデータベースとアプリケーションユーザーを作成する必要があります:

PostgreSQL

docker run -d --name takuto_db --network <takuto-network> \
  -e POSTGRES_USER=takuto \
  -e POSTGRES_PASSWORD='<DB_PASSWORD>' \
  -e POSTGRES_DB=takuto \
  -v takuto_db-data:/var/lib/postgresql/data \
  -p 5433:5432 \
  postgres:16-alpine

MariaDB

docker run -d --name takuto_db --network <takuto-network> \
  -e MARIADB_ROOT_PASSWORD='<ROOT_PASSWORD>' \
  -e MARIADB_DATABASE=takuto \
  -e MARIADB_USER=takuto \
  -e MARIADB_PASSWORD='<DB_PASSWORD>' \
  -v takuto_db-data:/var/lib/mysql \
  -p 3306:3306 \
  mariadb:11

MySQL

docker run -d --name takuto_db --network <takuto-network> \
  -e MYSQL_ROOT_PASSWORD='<ROOT_PASSWORD>' \
  -e MYSQL_DATABASE=takuto \
  -e MYSQL_USER=takuto \
  -e MYSQL_PASSWORD='<DB_PASSWORD>' \
  -v takuto_db-data:/var/lib/mysql \
  -p 3306:3306 \
  mysql:8

永続化: 上記の -v takuto_db-data:/… という名前付きボリュームこそが、container を 作り直してもデータが生き残るようにするものです。これがないと、container を削除した時点で データも消えます。

「Takuto のネットワーク」とはどれのこと? ここが多くの人がつまずく部分です。 Docker-in-Docker サイドカー が有効なとき、takuto container は 自分自身のネットワークを 持ちませんdind container のネットワーク名前空間を共有します(network_mode: service:dind)。したがって重要なのは、dind container がアタッチされているネットワーク (ふつうは Compose プロジェクトのデフォルト、例: takuto-core_default)であって、Takuto に ちなんだ名前のネットワーク ではありません。次のコマンドで見つけられます:

docker inspect <dind-container> | grep -A8 '"Networks"'

データベースを その ネットワークにアタッチし、そのネットワーク上での名前/エイリアスで 参照してください。

データベースがすでに別のネットワークで動いている? 作り直す必要はありません — Takuto の ネットワークへブリッジし、接続文字列が期待するエイリアスを与えましょう:

docker network connect --alias takuto_db <takuto-network> <your-db-container>

--alias takuto_db により、データベースはそのネットワーク上で takuto_db として名前解決 されるので、…@takuto_db:5432/… のような接続文字列はそのまま動き続けます。

ステップ 2 — config.toml に接続文字列を設定する

.takuto/config.toml[database] セクションを編集します:

[database]
connection = "<CONNECTION_STRING>"
fail_fast = true          # DB に到達できなければ起動を中断する(推奨)
import_from_sqlite = true # 初回接続時に既存のローカル SQLite データを移行する

エンジンに応じた スキームと内部ポート を使い、ホストにはデータベースの container 名 を 指定します:

エンジン接続文字列
PostgreSQLpostgresql://takuto:<DB_PASSWORD>@takuto_db:5432/takuto
MariaDBmysql://takuto:<DB_PASSWORD>@takuto_db:3306/takuto
MySQLmysql://takuto:<DB_PASSWORD>@takuto_db:3306/takuto

MariaDB と MySQL はどちらも mysql:// スキームを使います。内部 ポート(5432 / 3306)に 注意してください — -p で公開したポートではありません。

ステップ 3 — Takuto を再起動する

Takuto は起動時に config.toml を読み込むので、変更を適用するには再起動します:

takuto restart

ステップ 4 — 確認する

Takuto のログを確認します。接続に成功すると、次のようなログが出ます:

Multi-user database initialized (external backend)  backend="postgres"  url="postgresql://takuto:****@takuto_db:5432/takuto"

fail_fast = true のとき、設定が誤っていたり到達できないデータベースだと、起動は SQLite に 黙ってフォールバックするのではなく、エラーで 中断 します — つまり、きれいに起動できたなら 外部データベースが使われているということです。Takuto の egress 層も、ホストを認識すると Allowing database sidecar: takuto_db:5432 をログに出します。データベースに接続して、 Takuto のテーブル(userssessionscredentialsrepositories、…)が作成されている ことを確認することもできます。

ホストマシンから接続する(任意)

ローカルのクライアントでデータベースを覗くには、公開した ポート(-p)を使い、localhost 経由で接続します:

postgresql://takuto:<DB_PASSWORD>@localhost:5433/takuto
mysql://takuto:<DB_PASSWORD>@localhost:3306/takuto

ここが localhost で正しい唯一の場所です — Takuto container の内側からではなく、ホストから 接続しているからです。

トラブルシューティング

症状考えられる原因
起動時に pool timed out / connection refused文字列が <container-name>:<internal-port> の代わりに localhost や公開ポートを使っている。あるいは DB container が Takuto のネットワーク上にない。
起動時に Database backend unreachableよくある原因は 2 つ: (1) Takuto の 5 秒の SELECT 1 プローブが走った時点で、データベースがまだ接続を受け付けていなかった — 起動時の競合。(2) DB が Takuto のネットワーク上にない。対処: 同梱のオーバーレイを使う(DB のヘルスチェックを待ってくれます)、Takuto が起動する前に DB が起動して healthy になっていることを確かめる、または DB を dind container のネットワークにアタッチする(ステップ 1 を参照)。
起動が即座に中断するfail_fast = true で、DB に到達できないか認証情報が誤っている — 文字列/認証情報を修正してください。(fail_fast = false の場合は、警告をログに出して代わりに SQLite にフォールバックします。)
DB container を作り直したらデータが消えた名前付きボリュームをアタッチしていなかった。追加してください(ステップ 1)。
認証/アクセスエラーアプリ用のユーザー/データベースが作成されていない、または文字列内のパスワードが container の環境変数と一致していない。

キーの全一覧(プールのサイジング、タイムアウト、SQLite インポート)は [database] リファレンス を参照してください。