user icon

Docker公式イメージで開発用RDBをゲットだぜ(PostgreSQL編)

まえがき

Laravelでの開発時にデプロイ先はMySQLなのに手を抜いて手元の開発機ではSQLiteを使っていたら痛い目にあったりしました、muraveです。

開発環境にあまり影響を与えずにサクッと開発用のRDB(Relational Database)を建てられると素敵ですね。Docker公式イメージを活用すると出来そうです。

RDBというデッカイ単語を使っていますが、自分がよく使うPostgreSQL、MySQL、MariaDBなどについて調べようと思います。MySQLとMariaDB自体はほぼ同じ扱い方ができるRDBですが、公式イメージでの扱いはどうなんでしょうね。

記事にまとめながら試していこうと思います。Docker for Macを使用しており、今回はPostgreSQLです。

PostgreSQL

公式イメージを調べる

OFFICIAL REPOSITORY postgres

2016年8月中旬現在、以下のバージョンがあるようです。

9.6(9.6-beta4) , 9.5(9.5.4), 9.4(9.4.9), 9.3(9.3.14), 9.2(9.2.18), 9.1(9.1.23)

流石に8系はないですね。使いたくないですよね。忘れましょう。客先には残ってますが。

起動する

試していきます。せっかくですから9.6でやってみようと思います。

$ docker run -d --name postgres96beta4 -e POSTGRES_PASSWORD=mysecretpassword -p 15432:5432 postgres:9.6

公式の例を参考にコンテナの5432を15432にポートフォワードなど追加しておきました。

接続する

psqlでの接続ですが、公式には別コンテナを立ち上げての接続例が載ってますね。

$ docker run -it --rm --link postgres96beta4:postgres postgres:9.6 psql -h postgres -U postgres
Password for user postgres: 
psql (9.6beta4)
Type "help" for help.

postgres=# select version();
                                           version                                           
---------------------------------------------------------------------------------------------
 PostgreSQL 9.6beta4 on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit
(1 row)

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)

postgres=# \q

–rm を付けてあるので抜けるとコンテナは消えます。儚い。

ポートフォワードしてあるのでMacからつなぐこともできますが、当然、psqlのバージョンはMac上のものになります。

$ psql -h localhost -p 15432 -U postgres                      
Password for user postgres: 
psql (9.3.5, server 9.6beta4)
WARNING: psql major version 9.3, server major version 9.6.
         Some psql features might not work.
Type "help" for help.

postgres=# \q

9.3用なので警告がでています。

愛しのpgAdmin3でつないでみましょう。pgAdmin3も9.3用なので警告されております。

pgAdmin3でDockerコンテナ上のPostgreSQLに接続(バージョン警告)

接続はできました。

pgAdmin3でDockerコンテナ上のPostgreSQLに接続して操作

ほぼ使えましたがPostgreSQL9.6に対してツールのバージョンが9.3用と古いのでエラーがでたりもしますね。
psqlのみで作業するのはツライのでツールは対象に合わせたバージョンを用意しないとあかんなぁと思いました。

設定ファイルなど

コンテナのシェルを起動して探検。

$ docker exec -it postgres96beta4 bash  
root@d2e991bd61a7:/# cd /var/lib/postgresql/data/
root@d2e991bd61a7:/var/lib/postgresql/data# more postgresql.conf 

と、このようにpostgresql.confを眺めてみたり(lessもviもなかった)。

root@d2e991bd61a7:/var/lib/postgresql/data# more pg_hba.conf

pg_hba.confを眺めてみたり。pg_hba.confから抜粋しますと

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust

host all all 0.0.0.0/0 md5

ローカルからはtrustで他はパスワード認証ですかね。

拡張する

コンテナの /docker-entrypoint-initdb.d に拡張子がsql、shのファイルを置くとコンテナ起動時に実行してくれるそうです。
他、Dockerfileでdefault localeを設定するという例が公式のページに例として載っています。

やってみましょう。

日本語化されたイメージの作成

default localeを設定するDockerfileを作ります。

Dockerfile

FROM postgres:9.6

MAINTAINER murave

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

日本語化されたイメージ、mypostgres:9.6を作ります。

$ docker build -t mypostgres:9.6 ./

確認

$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
mypostgres           9.6                 4b7ea9f892dd        24 seconds ago      269.2 MB

データベースの初期化

操作しているディレクトリに/docker-entrypoint-initdb.d対応用にinitdbというディレクトリを作成しました。postgres/9.6/docker-entrypoint.sh を読んでみたところ

for f in /docker-entrypoint-initdb.d/*; do
    case "$f" in
        *.sh)     echo "$0: running $f"; . "$f" ;;
        *.sql)    echo "$0: running $f"; "${psql[@]}" < "$f"; echo ;;
        *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${psql[@]}"; echo ;;
        *)        echo "$0: ignoring $f" ;;
    esac
    echo
done

で順次処理となっているのでファイル名順に実行されるようです。sqlをgzip圧縮したsql.gz拡張子のファイルにも対応しているようですね。

初期化時にdockerユーザーとdockerテーブルを作成するshを作成します。

initdb/01adduser.sh

#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    CREATE USER docker;
    ALTER USER docker WITH PASSWORD 'dockerpassword';
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

次にsqlファイル内で\cでデータベースとユーザーをdockerに切り替えてテーブルを作ってみます。shでdb接続からしたほうが簡単な気がしますが、実験です。

initdb/02createtb.sql

\c docker docker

CREATE TABLE auth_group (
    id integer NOT NULL,
    name character varying(80) NOT NULL
);

COPY auth_group (id, name) FROM stdin;
1   Gyoumu
2   Master
3   System
\.

日本語化したmypostgres:9.6からMacのinitdbディレクトリを/docker-entrypoint-initdb.dにバインドしてコンテナを起動します。

$ docker run -d --name postgres96beta4 -e POSTGRES_PASSWORD=mysecretpassword -p 15432:5432 -v $(pwd)/initdb:/docker-entrypoint-initdb.d mypostgres:9.6

psqlで繋いで確認してみます(一応mypostgres:9.6イメージの方のものを使用)。

$ docker run -it --rm --link postgres96beta4:postgres mypostgres:9.6 psql -h postgres -U postgres
ユーザ postgres のパスワード: 
psql (9.6beta4)
"help" でヘルプを表示します.

postgres=# \l
 docker    | postgres | UTF8             | ja_JP.utf8 | ja_JP.utf8        | =Tc/postgres         +
           |          |                  |            |                   | postgres=CTc/postgres+
           |          |                  |            |                   | docker=CTc/postgres
 postgres  | postgres | UTF8             | ja_JP.utf8 | ja_JP.utf8        | 
 template0 | postgres | UTF8             | ja_JP.utf8 | ja_JP.utf8        | =c/postgres          +
           |          |                  |            |                   | postgres=CTc/postgres
 template1 | postgres | UTF8             | ja_JP.utf8 | ja_JP.utf8        | =c/postgres          +
           |          |                  |            |                   | postgres=CTc/postgres

postgres=# \c docker docker
ユーザ docker のパスワード: 
データベース "docker" にユーザ"docker"として接続しました。
docker=> \dt
 public   | auth_group | テーブル | docker

docker=> select * from auth_group;
  1 | Gyoumu
  2 | Master
  3 | System

docker=> \q

日本語化されたイメージを元に、01adduser.shでdockerユーザーを作成してパスワードを設定、dockerデータベースを作り、02createtb.sqlでdockerデータベースdockerユーザーに切り替えてauth_groupテーブルを作成し、データを流し込めていることが確認できました。

Docker Compose で開発用の PostgreSQL を起動する

日本語化したイメージを使用し、initdbのスクリプトで初期化、データの永続化はbusyboxを使用する方針でdocker-compose.ymlを作成します。

docker-composeでmysql & postgreSQL をサクッと起動

を参考にさせていただきました。

docker-compose.yml

postgres-data:
  image: busybox
  volumes:
      - /var/lib/postgresql/data
  container_name: postgres-datastore

postgresql:
  image: mypostgres:9.6
  environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: mysecretpassword
  volumes:
      - ./initdb/:/docker-entrypoint-initdb.d
  ports:
      - "15432:5432"
  container_name: postgres-db
  volumes_from:
      - postgres-data

起動します。

$ docker-compose up -d
Creating postgres-datastore
Creating postgres-db

以降、使用するあいだはstop・startで停止・起動していく感じでしょうか。

psqlやpgAdmin3で動作確認。OKでしたのでこれからはコレをベースに調整すれば簡単にPostgreSQLを準備できます。

ディレクトリファイル構成は以下のようになりました。

.
├── Dockerfile
├── docker-compose.yml
└── initdb
    ├── 01adduser.sh
    └── 02createtb.sql
Facebooktwitterlinkedintumblrmail

タグ: ,

名前
E-mail
URL
コメント

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)