『Docker』docker-composeで開発用PostgreSQLを手に入れる（ver.01）

## 1.目的
細かい設定まで行うことが出来るpostgreSQLのdocker-composeが欲しいので、Docker公式イメージをもとに試してみる。

dockerもpostgresqlも初心者なのでよりよい方法があればご教授お願いしますm(_ _)m

Docker導入までは以下を参照。
https://qiita.com/tsnb/items/d10d2770c08abc60b500

## 2.構築ver.01

公式の説明をもとに書いてみる。
https://docs.docker.com/samples/library/postgres/#environment-variables

ver.01でやりたいこと：

- (A).ロケールを日本語に変更する
- (B).初期化時にユーザとデータベースを作成する
- (C).postgresql.confを設定する  
      とりあえず、shared_buffers=256MBにしてみる
- (D).pgdataデータの永続化

```:ディレクトリ構造
|--Dockerfile
|--conf
|  |--my-postgresql-10.1.conf(shared_buffers=256MBに変更したもの)
|  |--postgresql-10.1.conf(オリジナルファイル、一旦docker runしてコピーしたもの)
|--data
|--01postgre.yml
|--work
|  |--init-user-db.sh(initdb時に行いたい処理を書く)
```

[host]はホストで実行するコマンド。

```bash
# 適当なディレクトリを作成
[host]$ mkdir -p ~/test/{work,data,conf}
[host]$ chown 1000 ~/test/{work,data,conf} #要らないか？

# ディレクトリに入る
[host]$ cd ~/test

# ~/testディレクトリ以下に、01postgre.ymlとDockerfileを置く。
# ~/test/workディレクトリ以下に、init-user-db.shを置く。

# postgres:10.1のコンテナを立ち上げて、ホストへ設定ファイルを持ってくる
[host]$ docker run --name temp -d postgres:10.1 /bin/bash
[host]$ docker cp temp:/usr/share/postgresql/ ./temp/
[host]$ cp ./temp/postgresql.conf.sample ./conf/postgresql-10.1.conf
[host]$ cat ./conf/postgresql-10.1.conf |sed "s/^#shared_buffers = 32/shared_buffers = 256/g" > ./conf/my-postgresql-10.1.conf

# tempディレクトリとコンテナは要らなければ削除しておく。

# 起動
[host]$ docker-compose -f ./01postgre.yml up -d --build

# コンテナ確認
[host]$ docker ps -a
CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS                  PORTS                              NAMES
5b8947145ece        test_postgres-ha                     "docker-entrypoint..."   14 minutes ago      Up 14 minutes           0.0.0.0:15432->5432/tcp            test_postgres-ha_1

# 出来たコンテナの名前を指定してコンテナに入る
# postgreでログイン出来ることがわかる
[host]$ docker exec -it test_postgres-ha_1 /bin/bash
postgres@5b8947145ece:/$ 

# (A)の確認：psqlでロケールがデフォルトからja_JP.UTF-8に変わっていることを確認。
# (B)の確認：dockerというユーザが出来ている。
$ psql -l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 docker    | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =Tc/postgres         +
           |          |          |             |             | postgres=CTc/postgres+
           |          |          |             |             | docker=CTc/postgres
 postgres  | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | 
 template0 | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(4 rows)

# (C)の確認：256MBの設定がホストからコピー出来ていることを確認。
$ cat /etc/postgresql/postgresql.conf |grep ^shared_buffers
shared_buffers = 256MB			# min 128kB

# (D)の確認：色々データがホスト上のディレクトリ内に出来ていることを確認。
[host]$ ls data/pgdata/
PG_VERSION  global        pg_dynshmem  pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    pg_wal   postgresql.auto.conf  postmaster.opts
base        pg_commit_ts  pg_hba.conf  pg_logical     pg_notify     pg_serial    pg_stat       pg_subtrans  pg_twophase  pg_xact  postgresql.conf       postmaster.pid

# listen_address
# 他のコンテナがポストグルにアクセスできるようにlisten_addresses = '*'を設定する
[host]$ cat conf/my-postgresql-10.1.conf |grep listen_address
listen_addresses = '*'

```



```yaml:01postgre.yml
version: '3'
services:
  postgres-ha:
    # Dockerfileでbuildしたものを実行
    # ロケールを変更するためにbuildを行う
    build:
      context: .

    environment:
      # ディレクトリの場所を指定
      PGDATA: /var/lib/postgresql/data/pgdata

      # この環境変数は、su権限を持つ指定されたユーザーと同じ名前のデータベースを作成
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "changeme"

      # エンコーディングを指定しておく
      # initdbで指定できる内容はここで指定可能
      # https://www.postgresql.org/docs/10/static/app-initdb.html を参照。
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=ja_JP.UTF-8"

    # ttyをtrueに設定しておくと、コンテナが起動し続ける
    tty: true
    restart: always
    
    # loginユーザを指定
    user: root

    # 追加の初期化を行う場合は、/docker-entrypoint-initdb.dに* .sql、* .sql.gz、* .shスクリプトを1つ以上追加する。
    # エントリポイントがinitdbを呼び出してデフォルトのpostgresユーザとデータベースを作成した後、
    # * .sqlファイルが実行され、そのディレクトリにある* .shスクリプトがすべてソースされ、
    # サービスを開始する前にさらに初期化が行われる。
    volumes:
      - ./work:/docker-entrypoint-initdb.d/

      # pgdataをホストに置く。データ永続化。
      - ./data/:/var/lib/postgresql/data/

    stdin_open: true
    ports:
      - "15432:5432"
    networks:
      - postgres-ha

networks:
  postgres-ha:
    driver: bridge
```

```bash:Dockerfile
# postgres:10.1を使用
FROM postgres:10.1

# ロケール設定
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8

# 作成した設定ファイルを/etc/postgresql以下にコピー
COPY ./conf/my-postgresql-10.1.conf /etc/postgresql/postgresql.conf

# config_fileを/etc/postgresql/postgresql.confに指定
CMD ["-c", "config_file=/etc/postgresql/postgresql.conf"]
```

```bash:init-user-db.sh
#!/bin/bash
set -e

# initdbでdockerというユーザとデータベースを作成する
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
	CREATE USER docker;
	CREATE DATABASE docker;
	GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

```

## おしまい