Docker for Mac で 日本語locale設定を含む PostgreSQL を構築

Docker for Macのパブリックベータが公開されたので、Docker for MacでPostgreSQLを構築してみます。
# 参考ページ
Docker for Mac Official
https://docs.docker.com/engine/installation/mac/

Docker Hub Postgres Official
https://hub.docker.com/_/postgres/
# Docker for Mac
https://docs.docker.com/engine/installation/mac/
インストーラをダウンロードして実行するだけで、ステータスバーにくじらが表示されてDockerが使えるようになります。超簡単ですね。

インストール要件は以下の通り。
- Mac must be a 2010 or newer model
- OS X 10.10.3 Yosemite or newer
- At least 4GB RAM
- VirtualBox prior to version 4.3.30 must NOT be installed

そして今回試したのは以下の環境。ギリギリですがひとつふたつコンテナあげるくらいだったら大丈夫そうです。
- MacBook Air (Mid 2011)
- OS X 10.11.5(El Capitan)
- 4GB RAM

Preferences - Advanced から Dockerが使用するCPUコア数とメモリを設定できますが、今回の環境では2CPU 2GBがデフォルト設定でした。
# Docker PostgreSQLコンテナの起動
ターミナルを立ち上げてコマンドを実行していきます。

バージョン確認。
`docker --version`
1.12.0-rc2になってますね。
`Docker version 1.12.0-rc2, build 906eacd, experimental`

Docker imageを取得。今回はpostgres:9.6のimageを取得します。接続先を指定しなければDocker HubのOfficialからimageを取得。
https://hub.docker.com/_/postgres/
`docker pull postgres:9.6`

Docker imageを確認。
`docker images`
その他にhello-worldとmysqlも表示されていますが、postgres:9.6がちゃんとありますね。

```
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              dfc90a840ff1        2 days ago          967 B
postgres            9.6                 991942450769        8 days ago          275.9 MB
mysql               5.7                 1195b21c3a45        3 weeks ago         380.2 MB
```

ちなみに、以下フォーラムでも質問がありましたが、docker imagesはデフォルトでは以下ファイルに保存されているようです。

```
＄HOME/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2`
```
https://forums.docker.com/t/where-are-images-stored-on-mac-os-x/17165


Dockerコンテナを起動します。
- --name コンテナ名を指定。
- -e 環境変数を指定、ここではPOSTGRES_PASSWORDでPostgreSQLのpostgresユーザのパスワードを設定。
- -d デタッチドモードで起動。バックグラウンド起動する場合に指定。
- REPOSITORY:TAGは最後に指定します

```
docker run --name postgres96 -e POSTGRES_PASSWORD=mysecretpassword -d postgres:9.6
```

Dockerコンテナの状態を確認します。パスワード設定以外はしなかったのでデフォルトの5432portで起動しています。
- -a 停止中のコンテナも含めて表示。
`docker ps -a`
起動しているようですね。

```
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
6a869317c174        postgres:9.6        "/docker-entrypoint.s"   8 minutes ago       Up 8 minutes        5432/tcp            postgres96
```

Dockerコンテナが出力したログが確認できます。
`docker logs postgres96`
init_dbなどが実行されているのが確認できますね。

```
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
(中略)
PostgreSQL init process complete; ready for start up.

LOG:  database system was shut down at 2016-07-02 10:13:14 UTC
LOG:  MultiXact member wraparound protections are now enabled
LOG:  database system is ready to accept connections
LOG:  autovacuum launcher started
```

Dockerコンテナに接続します。bashを使って直接接続します。
`docker exec -it postgres96 bash`
`root@6a869317c174:/# `


コンテナに接続できたら、psqlで接続できることを確認します。

```
psql -U postgres   
psql (9.6beta2)
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)
```

起動できていますね。

ここまでで起動はできましたが、Localeの設定がen_US.utf8になっています。Locale=Cと設定したい場合は起動時にオプションで渡せます。

Dockerコンテナの停止
`docker stop postgres96`

Dockerコンテナの削除
`docker rm postgres96`

これでさきほど立ち上げたコンテナは削除されたので改めて作り直します。

POSTGRES_INITDB_ARGSでlocaleを指定します。POSTGRES_PASSWORD等、複数のオプションを渡す場合はその都度-eが必要なようです。

```
docker run --name postgres96 -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_INITDB_ARGS="--encoding=UTF-8 --locale=C" -d postgres:9.6
```

```
psql -U postgres
psql (9.6beta2)
Type "help" for help.

postgres=# \l
                             List of databases
   Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges   
-----------+----------+----------+---------+-------+-----------------------
 postgres  | postgres | UTF8     | C       | C     | 
 template0 | postgres | UTF8     | C       | C     | =c/postgres          +
           |          |          |         |       | postgres=CTc/postgres
 template1 | postgres | UTF8     | C       | C     | =c/postgres          +
           |          |          |         |       | postgres=CTc/postgres
(3 rows)

postgres=# 
```

localeが変更できていることが確認できます。
# 日本語localeを含むDocker imageの作成と起動
ここまでくると日本語localeも使いたいところですが、そもそも元のimageにはen_US.utf8しかlocaleがはいっていないようです。Docker Hubのマニュアルに習って日本語localeを含むDocker imageをつくる必要があります。

まずは任意のディレクトリにて以下のDockerfileを作成。

```text:Dockerfile
FROM postgres:9.6
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8
```

Dockerfileを配置したディレクトリ上でdocker buildして postgres:9.6_ja というimageを作成します。
`docker build -t postgres:9.6_ja .`

```
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM postgres:9.6
 ---> 991942450769
Step 2 : RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
 ---> Running in 6f2189be1e51
 ---> bca4f0af9e7d
Removing intermediate container 6f2189be1e51
Step 3 : ENV LANG ja_JP.utf8
 ---> Running in bdcea137f68e
 ---> b93f6e3d0aca
Removing intermediate container bdcea137f68e
Successfully built b93f6e3d0aca
```

作成できたようです。docker imagesでも、TAGが9.6_jaになっているimageがあるのが確認できます。

```
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
postgres            9.6_ja              b93f6e3d0aca        7 seconds ago       278.5 MB
```

後は同じですね。上記imageを使ってdocker runで起動します。

```
docker run --name postgres96_ja -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_INITDB_ARGS="--encoding=UTF-8 --locale=C" -d postgres:9.6_ja
```

起動したコンテナに接続後、　psqlを起動すると日本語表示になっていることが確認できます。

```
psql -U postgres
psql (9.6beta2)
"help" でヘルプを表示します.

postgres=# \l
                                        データベース一覧
   名前    |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) |      アクセス権       
-----------+----------+------------------+----------+-------------------+-----------------------
 postgres  | postgres | UTF8             | C        | C                 | 
 template0 | postgres | UTF8             | C        | C                 | =c/postgres          +
           |          |                  |          |                   | postgres=CTc/postgres
 template1 | postgres | UTF8             | C        | C                 | =c/postgres          +
           |          |                  |          |                   | postgres=CTc/postgres
(3 行)

postgres=# 
```

いー感じですね。

ちなみに、ホストのポートとコンテナのポート番号をマッピングしてフォワーディングする場合は-pオプションをつけます。これはホストの5432とコンテナの5432ポートをマッピング。

```
docker run --name postgres96_ja -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_INITDB_ARGS="--encoding=UTF-8 --locale=C" -d -p 5432:5432 postgres:9.6_ja
```

以下の通り、PORTSがマッピングされます。
`docker ps -a`

```
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
59bd667ba5b2        postgres:9.6_ja     "/docker-entrypoint.s"   3 seconds ago       Up 2 seconds        0.0.0.0:5432->5432/tcp   postgres96_ja
```

# 感想
Docker ほぼはじめてさわりました。localeの設定等の確認にやや手間取ったものの、ただ起動するだけなら本当に一瞬ですね。これはたしかに便利。また色々とさわっていきたいと思います。