でじたるチリクラブ

旧くまでもぶたでもありません

Windows 10でDockerコンテナのPostgreSQLを動かす(2)

bannyaaa.hatenablog.jp

Windows 10でDockerコンテナのPostgreSQLを動かす(1)の続き。

環境

Windows 10でDocker Desktop (WSL 2バックエンド) がインストール済み。

  • Windows 10 Home: 20H2
  • Docker Desktop: 3.5.1
  • Docker Engine: 20.10.7

psqlでデータベースに接続(失敗)

コンテナで実行中のPostgreSQLデータベースにpsqlで接続する。

何も考えずに公式イメージのページにかかれたとおり、以下のコマンドを実行したところエラーになった。

> docker run -it --rm --network some-network postgres psql -h some-postgres -U postgres
docker: Error response from daemon: network some-network not found.

いったんdocker runコマンドのオプションの説明。

  • -it-i-tの組み合わせで、コンテナ内でインタラクティブな操作をするときに指定する。
  • -rmはコンテナを終了時に自動的に削除する。
  • --network <ネットワーク名>はコンテナを指定したネットワークに接続する。
  • psql以降はデータベースに接続するためのpsqlの実行とそのオプション。
    • -hは接続先データベースのホスト名。
    • -Uは接続先データベースのユーザ名。

このdocker runコマンドで行おうとしていることは、一時的に使う2個目のpostgresコンテナを実行し、その中でpsqlを起動してデータベースに接続すること。そしてエラーメッセージは、--networkオプションで指定しているネットワークが存在しないといっている。ここでの「ネットワーク」とは何ぞや、となったのでそこから調べてみた。

Dockerにおけるネットワーク

Dockerにはコンテナ同士の通信を行うためのネットワークという概念がある。

以下のコマンドで現在のネットワーク一覧を表示できる。

> docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
3a23672a0415   bridge    bridge    local
8c5b594cdf11   host      host      local
9add3ef94360   none      null      local

ここでは、はじめから作成済みのネットワークが3点出力されている。コンテナ実行時にネットワークを何も指定しなければ、bridgeが使われる。

ネットワークは追加することができる。

> 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

同一のネットワークを使っているコンテナ同士は通信ができる。ただし、デフォルトのbridgeネットワークを使うと、コンテナ名で通信先を指定することができない。そのためコンテナ同士の通信を行う際は、新規にネットワークをつくるアプローチが一般的なようだ。

公式イメージのページにかかれていたpsqlによる接続方法は、ネットワークsome-networkを作成し、PostgreSQLデータベースコンテナとpsql実行コンテナの両方をそのネットワークに属させる必要があったことがわかった。

ネットワークをきちんと理解するには時間がかかりそうだが、とりあえずここまで。

参考

Windows 10でDockerコンテナのPostgreSQLを動かす(1)

Dockerのお勉強をかねて、PostgreSQLをコンテナで動かせるようにする。

環境

Windows 10でDocker Desktop (WSL 2バックエンド) がインストール済み。

  • Windows 10 Home: 20H2
  • Docker Desktop: 3.5.1
  • Docker Engine: 20.10.7

PostgreSQLイメージの取得

PostgreSQLのイメージは、Docker Hubに上がっている公式イメージを利用する。

Docker Hubからローカルに最新(latest)イメージを取得する。

> docker pull postgres

PostgreSQLコンテナの実行

公式イメージのページに記載されているコマンドのとおり、コンテナを作成してpostgresインスタンスを起動してみる。

> docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres

以下はdocker runコマンドのオプションの説明。

  • --nameはコンテナに任意の名前をつけたいときに指定する。
  • -e環境変数を指定する。PostgreSQLのイメージの実行に必須となる、POSTGRES_PASSWORDにパスワードを設定する。
  • -dはコンテナをバックグラウンドのdetachedモードで実行する。デフォルトはフォアグラウンドのforegroundモード実行。
  • さいごのpostgresは実行対象のコンテナイメージの名前。

コンテナが動いているか確認する。

> docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED        STATUS         PORTS      NAMES
4656c729e721   postgres   "docker-entrypoint.s…"   1 second ago   Up 2 seconds   5432/tcp   some-postgres

コンテナを停止させるときはdocker stopコマンドを使う。

> docker stop <コンテナの名前>

dockerコマンドの補足

docker runはコンテナを作成して実行するコマンドで、作成するコンテナの名前はユニークである必要がある。あるコンテナが停止中であっても、別のコンテナを同じ名前でdocker runすると、以下のようにコンテナ名が既に使われているとエラーメッセージが出る。

> docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres
docker: Error response from daemon: Conflict. The container name "/some-postgres" is already in use by container "4656c729e7214c53f21e6e7952423106b9a6be3b930a63d3ea50c3588f478eba". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

停止中の作成済みコンテナを起動するときは、docker startコマンドを使う。

> docker start <コンテナの名前>

docker rmコマンドでコンテナを削除すれば、再び同じ名前でコンテナを作成できるようになる。

> docker ps -a
CONTAINER ID   IMAGE                             COMMAND                  CREATED          STATUS                        PORTS     NAMES
4656c729e721   postgres                          "docker-entrypoint.s…"   17 minutes ago   Exited (0) 13 minutes ago               some-postgres

> docker rm some-postgres
> docker ps -a
CONTAINER ID   IMAGE                             COMMAND            CREATED        STATUS                    PORTS     NAMES

> docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres

あるいは--nameでコンテナ名を指定しなければ、Dockerが重複しない名前を勝手につけてくれる。

> docker run -e POSTGRES_PASSWORD=mysecretpassword -d postgres
> docker ps
CONTAINER ID   IMAGE                             COMMAND                  CREATED         STATUS         PORTS
                               NAMES
fdd01f765286   postgres                          "docker-entrypoint.s…"   8 seconds ago   Up 7 seconds   5432/tcp                                      xenodochial_wilbur

参考