Laravelでの開発時にデプロイ先はMySQLなのに手を抜いて手元の開発機ではSQLiteを使っていたら痛い目にあったりしました、muraveです。
SQLiteって結構ルーズにつかえてしまうので手元の開発でSQLite使っててMySQL運用のサーバーにデプロイするとエラーがバンバンというのが昨日から連続発生中。
— murave (@murave) 2016年7月14日
開発環境にあまり影響を与えずにサクッと開発用のRDB(Relational Database)を建てられると素敵ですね。Docker公式イメージを活用すると出来そうです。
RDBというデッカイ単語を使っていますが、自分がよく使うPostgreSQL、MySQL、MariaDBなどについて調べようと思います。MySQLとMariaDB自体はほぼ同じ扱い方ができるRDBですが、公式イメージでの扱いはどうなんでしょうね。
記事にまとめながら試していこうと思います。Docker for Macを使用しており、今回はPostgreSQLです。
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用なので警告されております。
接続はできました。
ほぼ使えましたが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テーブルを作成し、データを流し込めていることが確認できました。
日本語化したイメージを使用し、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
Tags: Docker, PostgreSQL