Docker簡単構築データベース(PostgreSQL)

# TL;DR
Dockerでお手軽にPostgreSQLを作っちゃおうぜ、という記事である。
研修記事のためツール等々決め打ちにしてあるが、その辺はドンマイなのである。

# まずダウンロードを仕掛けとこう
今回SQLクライアントはDBeaverを使う。取り敢えず最新版をとってくれば良い。
https://dbeaver.io/

ダウンロード中にサクッとDBを立ち上げてしまおう。

# Docker Desktop for Windows
これがないと話にならない。まずはインストールしてしまおう。
https://docs.docker.jp/docker-for-windows/install.html

PowerShellで```docker ps```を叩いて以下のように出れば準備は完了だ。

```
> docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED        STATUS        PORTS                    NAMES
```

# では取り敢えずPostgreSQLを起動しよう
研修なので丁寧にイメージの探し方から。
以下```>```の後ろがコマンドである。

```
> docker search postgres
NAME                                    DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
postgres                                The PostgreSQL object-relational database sy…   8763      [OK]
```

検索するとサクッと見つかった。基本的にはOFFICIAL（公式）のイメージを取るのがベターだ。

ここで以下コマンドである。

```
docker run -d --rm --name db -p 5555:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres
```

イメージをダウンロードしてきて起動する。
コマンドの説明は後述。```docker ps```でコンテナが起動していれば完了である。

```
> docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS          PORTS                    NAMES
9676081a5f72   postgres   "docker-entrypoint.s…"   46 seconds ago   Up 46 seconds   0.0.0.0:5555->5432/tcp   db
```

# DBeaverはダウンロードできたかな
インストールして立ち上げてみよう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117698/9ab9c4b0-0d7f-af88-9a52-6dd932f7d3e5.png)

ポートを5555で。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117698/922114e7-115a-3f7d-c628-30eadb502540.png)

接続できたかな？
テーブルやカラムを作ってみよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117698/ce240c12-3d18-5846-2b89-9bdb26731b13.png)

今回は以下の様に「テストテーブル」というのを作ってみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117698/bf694431-146a-9309-7998-8ed2e748ff2f.png)


# psqlで繋いでみる
```docker exec -it db bash```でコンテナに接続。

```
> docker exec -it db bash
root@9676081a5f72:/#
```

```
root@9676081a5f72:/# psql -U postgres
psql (13.0 (Debian 13.0-1.pgdg100+1))
Type "help" for help.

postgres=# \db
       List of tablespaces
    Name    |  Owner   | Location
------------+----------+----------
 pg_default | postgres |
 pg_global  | postgres |
(2 rows)

postgres=# \dt
             List of relations
 Schema |      Name      | Type  |  Owner
--------+----------------+-------+----------
 public | テストテーブル | table | postgres
(1 row)

postgres=#
```

ちゃんとできてるね。```\q```で抜けて、```exit```でコンテナから脱出しよう。

# このコンテナは終わったら消えるしデータも永続化されない
```
> docker ps --all
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS                        PORTS                    NAMES
9676081a5f72   postgres          "docker-entrypoint.s…"   20 minutes ago   Up 20 minutes                 0.0.0.0:5555->5432/tcp   db
```

今はこのように存在しているが、このコンテナを止めてみよう。
```docker stop db```だ。

ちゃんと消えてるかな？

```
> docker ps --all
CONTAINER ID   IMAGE             COMMAND                  CREATED        STATUS                        PORTS                    NAMES
```

# 今回のDockerコマンドの説明
この一行でサクッとDBが起動してしまった。マジDockerさん神くね？

```
docker run -d --rm --name db -p 5555:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres
```

|  |概要|備考|
|---|---|---|
|run|起動|https://docs.docker.jp/engine/reference/run.html|
|-d|デタッチド|要するにバックグラウンド|
|--rm|コンテナ終了時にコンテナを削除|必須ではない docker rm dbで自分で消してもいい|
|--name db|コンテナ名|今回は**db**とした。省略可|
|-p 5555:5432|ポートフォワーディング|コンテナの5432をホストの5555へ|
|-e POSTGRES_HOST_AUTH_METHOD=trust|パスワードなし|パスワードをつける場合は**-e POSTGRES_PASSWORD=password**を使おう|
|postgres|イメージ名|searchで調べた奴|

# おまけ（docker-composeと永続化）
docker-composeのフォルダ構成とDockerfileとdocker-compose.ymlのサンプル。
このサンプルではホストの5434で反応するはず。
**services**に**app**を追加して、db-netを介してアプリからDBにすぐ接続。
init.sqlにDBとかテーブルとか作るSQLを入れておく、というイメージ。
結構前に作ったものだから古かったりイケてない書き方とかあっても許してね。

```
./
- docker-compose.yml
+ database/
  - Dockerfile
+ postgres-init/
  - init.sql
+ postgres/
```

```Dockerfile
FROM postgres:9.6.16

RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8
```

```docker-compose.yml
version: "3.5"

services:
  db:
    build:
      context: database
    volumes:
      - ./postgres:/var/lib/postgresql
      - ./postgres-init:/docker-entrypoint-initdb.d
    expose:
      - '5432'
    ports: 
      - "5434:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
    restart: 'always'
    networks:
      - db-net

networks:
  db-net:
    driver: bridge
```