English: README.NETWORKING.md
接続フォームに
localhostと入れたのに、データベースはすぐそこにあるのに 「connection refused」になった——そんな経験があるなら、このページはあなたの ためのものです。なぜそうなるのかを説明し、よくある構成ごとにコピペで効く 対処を載せます。
cli2ui は自分専用の Docker コンテナの中で動いています。コンテナの中で動く
コードにとって localhost は 「このコンテナ自身」 を指します——あなたの
マシンではありません。データベースが cli2ui のコンテナの中にいることはまず
ないので、localhost は見当違いの場所を指し、接続に失敗します。
┌─────────────────── あなたのマシン("ホスト")───────────────────┐
│ │
│ ┌── cli2ui コンテナ ──┐ ┌── postgres コンテナ ──┐ │
│ │ │ │ │ │
│ │ localhost ─────────┼──┐ │ 5432 で待ち受け中 │ │
│ │ = このコンテナ ✗ │ │ │ │ │
│ └─────────────────────┘ │ └───────────────────────┘ │
│ │ │
│ └─► cli2ui 自身に戻ってしまい、 │
│ DB ではない → "connection refused"│
└──────────────────────────────────────────────────────────────────┘
つまり勝負どころは 「cli2ui がどんな名前でデータベースを探すか」 です。答えは データベースがどこで動いているかで変わります。下から自分の状況を探してください。
| データベースはどこで動いている? | 使う host の値 | 移動先 |
|---|---|---|
| マシンにネイティブ導入(Homebrew, Postgres.app, インストーラ) | host.docker.internal |
ケース A |
別の Docker コンテナ(別の docker compose プロジェクト) |
データベースのコンテナ名 | ケース B |
ポートを公開しているコンテナ(-p 5432:5432) |
host.docker.internal |
ケース C |
port は常にデータベース自身が待ち受けるポートです(PostgreSQL の既定は
5432)——例外は各ケースの注記を参照。
データベースが Docker ではなく、マシン上の普通のプログラムとして動いている場合。
cli2ui の docker-compose.yml には、これを成立させる仕掛けが最初から入って
います——コンテナの中から「ホストマシン」を指す名前を与える extra_hosts です:
extra_hosts:
- "host.docker.internal:host-gateway"接続フォームには:
| 項目 | 値 |
|---|---|
| host | host.docker.internal |
| port | 5432(ローカル Postgres が使うポート) |
| db / user / password | あなたのデータベースのもの |
host.docker.internal は、コンテナの中から あなたのマシン を指す特別な名前で、
Docker が解決します。ここでは macOS・Windows・Linux のいずれでも同じように動き
ます。
「実プロジェクト」で最もよくあるケースです:アプリとその DB が既に独自の
docker compose 構成で動いていて、その DB を cli2ui から覗きたい、という状況。
コンテナ同士は 同じネットワーク上にいるときだけ 名前で呼び合えます。cli2ui は
自分専用のネットワーク(cli2ui_default)で起動するので、まず cli2ui を DB の
ネットワークに参加させ、その上で DB を コンテナ名 で指定します。
docker ps # 動いているコンテナ名を表示
docker network ls # ネットワーク一覧DB コンテナの NETWORKS 列を見ます。myapp という名前の compose プロジェクトは
普通 myapp_default というネットワークを作ります。
docker network connect <db-network> cli2ui-app-1(cli2ui-app-1 は docker compose up で起動したときの cli2ui コンテナ名です。
docker ps で確認してください。)
| 項目 | 値 |
|---|---|
| host | DB の コンテナ名(例 myapp-db) |
| port | 5432 |
| db / user / password | あなたのデータベースのもの |
これで完了です——誰の compose ファイルも編集せず、コンテナを止めるまで有効です。
後で外すには docker network disconnect <db-network> cli2ui-app-1。
恒久的にしたい?
network connectの代わりに、両プロジェクトを1つの共有 外部ネットワークに載せます:docker network create shared-net# 両方の docker-compose.yml に追記: networks: default: name: shared-net external: trueこうすると常にコンテナ名で到達でき、手動手順が不要になります。
DB のコンテナがポートをマシンにマッピングしている場合——docker ps に
0.0.0.0:5432->5432/tcp のように出ます——マシンから見れば DB はホスト上で到達
可能です。ケース A と同じくホスト経由を使います:
| 項目 | 値 |
|---|---|
| host | host.docker.internal |
| port | 公開側(左側)のポート——例 5432、5433:5432 なら 5433 |
| db / user / password | あなたのデータベースのもの |
これならネットワークを一切いじらずに済みます。ただし トラブルシュートの macOS 注意点を参照——別の データベースが既にそのポートをマシン上で握っている場合は、 ケース B のほうが確実です。
データベースが既に自分の管理する docker compose プロジェクトにいるなら、いちばん
綺麗なのは cli2ui をその同じ compose にサービスとして足すことです(別スタック
として動かすのではなく)。同じプロジェクトのネットワークに自動で乗るので、cli2ui は
データベースに コンテナ名 で到達でき、ネットワーク設定はゼロ——起動するコンテナ
群も増えません。
自分のプロジェクトの docker-compose.yml にこう足します:
services:
# ... 自分のアプリ、自分の db(例: サービス名 `db`)...
cli2ui:
image: cli2ui-app # 先に1回ビルド: docker build -t cli2ui-app /path/to/cli2ui
profiles: ["tools"] # 明示したときだけ起動(下記参照)
ports:
- "8001:8000" # 8000 はアプリが使うことが多い—空きホストポートを選ぶ
restart: unless-stopped起動は 必要なときだけ:
docker compose --profile tools up # 自分のスタック + cli2ui を起動http://localhost:8001 を開き、host = 自分の db のサービス名(例 db)・port
5432・自分の資格情報で接続します。
外さないための3点:
profilesで開発専用に隔離する。 cli2ui に認証はありません。profiles: ["tools"]を付けると、ただのdocker compose upでは起動せず、--profile toolsを付けたときだけ立ち上がります。これが「共有環境や本番スタックにうっかり 同居する」ことへの保険です。- cli2ui 同梱の
sampledbは持ち込まない。 向けたいのは自分のデータベース (サービス名で指定)であってデモDBではありません。上のcli2uiサービス1つで 十分で、ビルド済みのcli2ui-appイメージを参照すれば cli2ui 自身の compose や build context から切り離せます。 - 空きのホストポートを使う(ここでは
8001:8000)——アプリと衝突しないように。
保存した接続・履歴はコンテナ内の
db.sqlite3にあるので、コンテナが作り直さ れるとリセットされます——開発ツールとしては許容範囲(接続の入れ直しは数秒)。残し たいなら、ファイルを bind mount してください(事前に作成した./.cli2ui-db.sqlite3:/app/db.sqlite3)。
別アプリ SyncVey が Docker で動いていて、その DB コンテナが
syncvey-db、ネットワークが syncvey_default だとします。一連の流れは
こうです(これはケース B):
# 1. 何がどこで動いているか確認
docker ps
# NAMES IMAGE NETWORKS
# syncvey-db postgres:18-alpine syncvey_default ← 接続先
# 2. cli2ui を起動(8000 が埋まっている場合に備えホスト側 8001)
docker run -d --name cli2ui-app-1 -p 8001:8000 cli2ui-app
# 3. cli2ui を SyncVey のネットワークに参加させる
docker network connect syncvey_default cli2ui-app-1
# 4. http://localhost:8001 を開きフォームに入力:
# host = syncvey-db port = 5432
# db = <相手のDB> user/password = <相手のもの>これで cli2ui は syncvey-db を名前で解決して接続できます。完了。
| 症状 | 考えられる原因 | 対処 |
|---|---|---|
host を localhost にすると connection refused |
localhost = cli2ui コンテナ自身であり DB ではない |
host.docker.internal(ケース A/C)か、コンテナ名(ケース B)を使う |
could not translate host name "<名前>" |
cli2ui がそのコンテナと同じネットワークにいない | docker network connect <db-network> cli2ui-app-1(ケース B) |
host.docker.internal で繋がるが 別の DB に当たる |
そのポートを別の DB が既にマシン上で握っている(macOS でネイティブ Postgres が 5432 を握り、コンテナの公開 5432 を隠すのが典型) |
ケース B(共有ネットワーク上でコンテナ名)を使う——曖昧さがない |
コンテナの IP(例 172.x.x.x)にマシンから届かない |
Docker Desktop(macOS/Windows)ではコンテナ IP はホストからルーティング不可 | IP を使わず、ケース B(コンテナ名)かケース C(公開ポート)で |
| 動いていたのに再起動後に壊れる | docker network connect はコンテナの寿命限り |
up のたびに再実行するか、ケース B の恒久共有ネットワーク構成にする |
- コンテナ内の
localhost= そのコンテナ自身。 ほぼ確実にあなたの DB ではない。 host.docker.internal= あなたのマシン(ネイティブ導入の DB や、ホスト ポートに公開された DB 向け)。- コンテナ名は同じ Docker ネットワークにいるときだけ有効——まず
docker network connectで参加する。 - macOS/Windows の Docker Desktop では、コンテナの IP アドレス はマシン から到達不可。常に名前か公開ポートで。
それでも詰まったら、docker ps と docker network ls の出力、そしてフォームに
どう入力したかを添えて issue を開いてください。