psqlクライアントを使い捨てのDockerコンテナで代用する方法

# はじめに
本記事では、psqlクライアントをDockerコンテナで代用する方法をご紹介します。
Dockerコンテナを使うとホストを汚すことなく、psqlクライアントを非常に簡単に取り扱うことができます。
また、複数バージョンのPostgreSQLをお使いになっている方は、psqlクライアントのバージョン切り替えを何らかの方法で行われていると思います。
そのような方もDockerコンテナを使ったバージョンの切り替えを一つの選択肢として考えてみてください。

# 使用環境
- macOS Mojave v10.14.6
- DockerEngine v19.03.5

# 1. 前準備
## 1-1. dockerのネットワークを作成
ネットワークは、次節で作成するデータベースに接続する際、ホストの名前解決に必要なため作成しておきます。

```
$ docker network create psql-test-nw
$ docker network ls -f name=psql-test-nw
NETWORK ID          NAME                DRIVER              SCOPE
e41f62339fbc        psql-test-nw        bridge              local
```

## 1-2. 接続用にPostgreSQLデータベースを起動する
データベースもDockerコンテナを使います（[イメージはこちら](https://hub.docker.com/_/postgres)）。
タグは`9.6.16`を指定します。
デフォルトでは、ユーザー名とデータベース名ともに`postgres`で作成されます。
パスワードだけは初期設定されませんので設定する必要があります（ここでは、`postgres`で設定します）。
※接続できるかどうかのテストを行うことが目的であるため、ボリュームのマウント（データの永続化）は行なっていません。

```
$ docker run --name postgresql-db -h postgresql-db --network psql-test-nw -e POSTGRES_PASSWORD=postgres -d postgres:9.6.16
```

それでは、コンテナの起動状況を確認してみます。
次のように表示されればOKです。

```
$ docker container ls -f name=postgresql-db
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
542215b226d5        postgres:9.6.16     "docker-entrypoint.s…"   3 seconds ago       Up 2 seconds        5432/tcp            postgresql-db
```

# 2. psqlクライアントを使い捨てDockerコンテナで代用する
## 2-1. 実際に接続してみる
次のdockerコマンドを実行すればパスワードを聞かれるので、先ほどデータベース作成時に指定した`postgres`を入力して接続できます。
この時`--rm`オプションは忘れずにつけましょう。

```
$ docker run --rm --name psql-client --network psql-test-nw -it postgres:9.6.16 psql -h postgresql-db -U postgres -p 5432 postgres
Password for user postgres: 
psql (9.6.16)
Type "help" for help.

postgres=#
```

今回`--name`オプションをつけているのは、データベースからデタッチした後にpsqlコンテナが消えているかを確認するためです。
まず、デタッチする前に別のシェルを開いてコンテナの起動を確認してみます。

```
$ docker container ls -f name=psql-client
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
a9c02493cbbe        postgres:9.6.16     "docker-entrypoint.s…"   3 minutes ago       Up 3 minutes        5432/tcp            psql-client
```

起動していることを確認できました。
それでは、デタッチしてコンテナが自動削除されていることを確認します。

```
postgres=# \q

$ docker container ls -f name=psql-client
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

ちゃんと消えていますね！
このようにpsqlクライアントはdockerコンテナで代用できます。
バージョンの切り替えはタグを切り替えるだけで事足ります。

# 3. おまけ

## 3-1. Amazon RDSに接続してみる
1, 2の例では、コンテナ同士の名前解決のため`docker network`を使いましたが、今回はエンドポイントURIで名前解決できるので必要ありません。

```
$ docker run --rm -it postgres:9.6.16 psql -h postgresql-db.abcdefghijkl.ap-northeast-1.rds.amazonaws.com -p 5432 -U postgres postgres
Password for user postgres: 
psql (9.6.16)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=>
```

## 3-2. エイリアスを作成する
次の2行を`.bash_profile`や`.zshrc`に記載するだけです。

```
export PSQL_VERSION="9.6.16"
alias psql="docker run --rm -it postgres:$PSQL_VERSION psql"
```

バージョンを切り替える際は、`.bash_profile`や`.zshrc`のバージョンを書き換える必要があります。
このエイリアスにより、3-1のRDSへの接続は以下で書き換えられます。

```
psql -h postgresql-db.abcdefghijkl.ap-northeast-1.rds.amazonaws.com -p 5432 -U postgres postgres
```

# まとめ
いかがでしたでしょうか？
この方法を使えば非常に簡単にpsqlのセットアップができます。
また、未確認ですが、同様の方法でmysqlクライアントもDockerコンテナで代用できるでしょう。
是非使ってみてください。