Takuto で外部データベースを使う
デフォルトでは、Takuto はデータをローカルの SQLite ファイル(データディレクトリ内の
takuto.db)に保存します。マルチユーザー構成や本番運用では、代わりに外部の PostgreSQL、
MariaDB、MySQL データベースに 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 が同じネットワークを共有していることを確かめてください。
- ❌
localhostや127.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 サイドカー が有効なとき、
takutocontainer は 自分自身のネットワークを 持ちません —dindcontainer のネットワーク名前空間を共有します(network_mode: service:dind)。したがって重要なのは、dindcontainer がアタッチされているネットワーク (ふつうは 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 名 を 指定します:
| エンジン | 接続文字列 |
|---|---|
| PostgreSQL | postgresql://takuto:<DB_PASSWORD>@takuto_db:5432/takuto |
| MariaDB | mysql://takuto:<DB_PASSWORD>@takuto_db:3306/takuto |
| MySQL | mysql://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 のテーブル(users、sessions、credentials、repositories、…)が作成されている
ことを確認することもできます。
ホストマシンから接続する(任意)
ローカルのクライアントでデータベースを覗くには、公開した ポート(-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] リファレンス を参照してください。