docker_pgsql

Dockerでつくる開発環境【PostgreSQLコンテナ編】

前回まででnginx+phpの環境が整いましたので、今回はデータベースサーバのコンテナを作ってphpから接続してみます。
これができれば、PostgreSQLではなくMySQLなど別のデータベースサーバでも同様に作れると思います。

Dockerfile

今回もまずはDockerfileを見てみましょう。

FROM ubuntu:14.04

MAINTAINER d-abe 

RUN apt-get update && \
    apt-get install -y -q postgresql-9.3 libpq-dev postgresql-client-9.3 postgresql-contrib-9.3 && \
    rm -rf /var/lib/apt/lists/*

USER postgres
RUN /etc/init.d/postgresql start &&\
    psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\
    psql --command "CREATE DATABASE docker WITH OWNER docker TEMPLATE template0 ENCODING 'UTF8';" &&\
    echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/9.3/main/pg_hba.conf &&\
    echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf

EXPOSE 5432
VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]

今までと同様apt-getでインストールを行い、データベース接続用のユーザとデータベースを作成しています。
接続許可設定もあわせて行っています。

早速これをビルドします。

$ docker build -t test/postgresql ./

PostgreSQLコンテナの起動

PostgreSQLコンテナについては起動時にそれほど気をつけるところはありません。
ポート5432をマッピングしておけばOKだと思います。

$ docker run -d -p 5432:5432 --name postgresql test/postgresql

接続テスト

起動に成功したら、pgAdminなどのツールで接続できるかどうか試してみましょう。
私の場合は、Navicatを使っています。接続先はdocker-machine ip で出てくるIPを入れ、ユーザ名、パスワード、データベース名はdockerにして接続します。

docker_pgsql_connected

うまくいけばこのようになります(が、テーブルも何もないので一覧に何も表示されません)。

ここへ、とりあえずテストデータを投入します。
以下の記事を参考にしてテスト用のテーブルとデータを作ります。

» PostgreSQL: 集合を返すGENERATE_SERIES関数で大量データを生成して集計する TECHSCORE BLOG

CREATE TABLE sales
(
  -- 売上日.
  sold_on DATE NOT NULL,
 
  -- 売上金額.
  amount INTEGER NOT NULL
);

CREATE INDEX "idx_sales_sold_on" ON "public"."sales" USING btree(sold_on ASC NULLS LAST);
COMMENT ON INDEX "public"."idx_sales_sold_on" IS NULL;

INSERT INTO
  sales (sold_on, amount)
SELECT
  '2016-01-01'::DATE + (RANDOM() * 31)::INTEGER AS sold_on,
  (RANDOM() * 1000)::INTEGER + 1000 AS amount
FROM
  -- 100 件生成
  GENERATE_SERIES(1, 100)
ORDER BY
  sold_on
;

SQLを実行すると、salesテーブルが作成されてデータが100件入ると思います。

docker_pgsql_data

php-phalconコンテナの起動

まず、前回までのコンテナが起動している場合は一度削除してください(docker rm -f コマンド)。
今回はDBへのアクセスを試すので、phpのソースコードも以下のように変更します。

<?php

use Phalcon\Db\Adapter\Pdo\Postgresql as PostgresAdapter;
use Phalcon\Mvc\Micro;

$app = new Micro();

$app["db"] = function () {
	return new PostgresAdapter(
		[
			"host" => "db",
			"username" => "docker",
			"password" => "docker",
			"dbname" => "docker",
		]
	);
};

$app->get('/', function () use ($app) {
	$sales = $app["db"]->query("SELECT
	  dates.day,
	  (SELECT SUM(amount) FROM sales WHERE sold_on=dates.day) AS amount
	FROM
	  (SELECT '2016-01-01'::DATE + GENERATE_SERIES(0, 30) AS day) AS dates
	;");
	echo json_encode(["result" => $sales->fetchAll(\Phalcon\Db::FETCH_ASSOC)]);
});

$app->handle();

日付ごとの合計を集計してjsonで値を返すだけの簡単なプログラムです。

そして、php-phalconのコンテナですが、今回は以下のコマンドとオプションで実行します。

$ docker run -d -v /Users/abe/dockers/www:/var/www --link postgresql:db --name phalcon  test/phalcon

前回と違うのは ––link オプションです。

––linkオプション

––link container:alias の形式で指定するこのオプションは、runさせるコンテナから––linkで指定したcontainerにネットワーク的にアクセスができるようにするものです。

これを指定すると

ALIAS_PORT_5432_TCP_ADDR=172.17.0.2
ALIAS_PORT=tcp://172.17.0.2:5432
ALIAS_PORT_5432_TCP=tcp://172.17.0.2:5432
ALIAS_PORT_5432_TCP_PORT=5432

という環境変数がrunしたコンテナに自動的に設定されます。
また、それだけではなく/etc/hostsも自動的に書き換えられます。

phpからだとALIAS_PORT_5432_TCP_ADDRとかを$_ENVの環境変数から取得できなくて困ったのですが、/etc/hostsに自動でセットされていたので、エイリアスをホスト名としてphpのコード内でそのまま使うことができます!(話が前後しますが先のphpソースコードの"host"のところ参照)

nginxコンテナの起動

nginxコンテナの起動方法は前回と全く同じです。

$ docker run -d -v /Users/abe/dockers/www:/var/www --name nginx -p 80:80 -v /Users/abe/dockers/conf/phalcon_nginx.conf:/etc/nginx/sites-enabled/default --volumes-from phalcon nginx

パラメータの都合上、必ず postgresql => php => nginx の順に起動する必要があります。

動作確認

nginxコンテナが起動したら、ブラウザで動作確認をしてみましょう。

docker_pgsql_result

json出力をブラウザでそのまま表示しているでごちゃごちゃしていますが正常に動作しているようです。

問題点など

一応ひととおりこれで動作が確認できましたが、いろいろ問題点があります。
まず、今回のイメージにはデータベースユーザ名やパスワード、データベース名などが決め打ちされています。とりあえず動かすのとDockerfileの書き方の勉強が目的だったのでこのようにしましたが、実際にはイメージの外にこのような情報はおくべきです(依存性を排除したいので)。

公式イメージでは、runの際の-eオプションでこういった値を渡すことができるようになっているので、実際にはそちらを使った方が良さそうです。

公式イメージを使う場合は、docker pull postgres、またはDockerfile内で FROM postgres:TAG とすればOKです。

もう一点、気になるところとしては、各コンテナの起動オプションが多いのと起動順を守らないといけないところです。
これについては、docker-composeというものを使えば解決できます。次回はそれについて勉強したいと思います。

LINEで送る
Pocket

コメント “Dockerでつくる開発環境【PostgreSQLコンテナ編】

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です