前回、psqlでコンテナで実行中のPostgreSQLに接続しようとして失敗したところからの続き。
環境
Windows 10でDocker Desktop (WSL 2バックエンド) がインストール済み。
- Windows 10 Home: 20H2
- Docker Desktop: 3.5.2
- Docker Engine: 20.10.7
psqlでデータベースに接続する(成功)
psqlによるデータベースへの接続について、PostgreSQL公式イメージのページに記載されていた、ネットワークを新規に作成するアプローチ以外にも方法がないか調べた。 結果的に、以下の3通りの方法でpsqlからPostgreSQLに接続できそうであることがわかり、実際に試してみた。
- psql実行コンテナから、同一ネットワーク内のデータベースコンテナに接続する。(前回失敗した方法)
- データベースを実行中のコンテナにアタッチし、コンテナの中からpsqlで接続する。
- データベースコンテナ実行時にコンテナからホストにポートを割り当て、ホストからpsqlで接続する1。
1. 同一ネットワーク内のコンテナ間通信で接続する
まずはじめにコンテナをつなぐネットワークを作成しておく。
> docker network create some-network > docker network ls NETWORK ID NAME DRIVER SCOPE de7e1d508a4e bridge bridge local 8c5b594cdf11 host host local 9add3ef94360 none null local 13730a030319 some-network bridge local
PostgreSQLデータベース用とpsql実行用の2つのコンテナを、作成したネットワークsome-network
に接続する形で順番に実行する。psqlコマンドの接続先のホスト名には、PostgreSQLデータベース用コンテナの名前であるsome-postgres1
を指定する。
> docker run --name some-postgres1 --network some-network -e POSTGRES_PASSWORD=mysecretpassword -d postgres > docker run -it --rm --network some-network postgres psql -h some-postgres1 -U postgres Password for user postgres: psql (13.3 (Debian 13.3-1.pgdg100+1)) Type "help" for help. postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+----------------------- postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (3 rows)
2. 実行中のコンテナへのアタッチで接続する
実行中のコンテナでコマンドを実行できるdocker exec
コマンドを用いる。
はじめにPostgreSQLデータベースのコンテナを実行し、続いてdocker exec
コマンドでPostgreSQLデータベースコンテナを指定してbash
を実行する。
> docker run --name some-postgres2 -e POSTGRES_PASSWORD=mysecretpassword -d postgres > docker exec -it some-postgres2 /bin/bash
するとPostgreSQLデータベースコンテナの中に入れるので、postgresユーザへ切り替えてからpsqlを起動し、localhostのデータベースに接続すればよい。
root@8f64d61fc808:/# su - postgres postgres@8f64d61fc808:~$ psql -h localhost -U postgres postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+----------------------- postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (3 rows)
3. コンテナからホストへのポート割り当てで接続する
コンテナのポートに対してホストからは基本的に通信することができない。ただし、docker run
コマンド実行時に-p
もしくは--publish
オプションを指定し、-p <ホストのポート>:<コンテナのポート>
とすることでコンテナのポートをホストに割り当てて通信することができるようになる。
コンテナのポート5432
をホストの54321
に割り当てて、PostgreSQLデータベース用コンテナを実行する。
> docker run -p 54321:5432 --name some-postgres3 -e POSTGRES_PASSWORD=mysecretpassword -d postgres
ホストにインストール済みのpsqlを、localhostのポート54321
を指定して起動する。
> psql -p 54321 -h localhost -U postgres Password for user postgres: psql (13.3) Type "help" for help. postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+----------------------- postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (3 rows)
ちなみにコンテナからホストへのポート割り当て状況は、docker port
コマンドで確認できる。
> docker port some-postgres3 5432/tcp -> 0.0.0.0:54321 5432/tcp -> :::54321
参考
- Stack Overflow - Connecting to Postgresql in a docker container from outside
- Docker ドキュメント日本語化プロジェクト - ホスト上にコンテナのポートを割り当て
-
ホストにpsqlのインストールが必要 (今回はPostgreSQL 13.3のインストール時にCommand Lineオプションにチェックして導入) ↩