前回まででnginx+phpの環境が整いましたので、今回はデータベースサーバのコンテナを作ってphpから接続してみます。
これができれば、PostgreSQLではなくMySQLなど別のデータベースサーバでも同様に作れると思います。
目次
Dockerfile
今回もまずはDockerfileを見てみましょう。
FROM ubuntu:14.04 MAINTAINER d-abeRUN 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
うまくいけばこのようになります(が、テーブルも何もないので一覧に何も表示されません)。
ここへ、とりあえずテストデータを投入します。
以下の記事を参考にしてテスト用のテーブルとデータを作ります。
» 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件入ると思います。
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コンテナが起動したら、ブラウザで動作確認をしてみましょう。
json出力をブラウザでそのまま表示しているでごちゃごちゃしていますが正常に動作しているようです。
問題点など
一応ひととおりこれで動作が確認できましたが、いろいろ問題点があります。
まず、今回のイメージにはデータベースユーザ名やパスワード、データベース名などが決め打ちされています。とりあえず動かすのとDockerfileの書き方の勉強が目的だったのでこのようにしましたが、実際にはイメージの外にこのような情報はおくべきです(依存性を排除したいので)。
公式イメージでは、runの際の-eオプションでこういった値を渡すことができるようになっているので、実際にはそちらを使った方が良さそうです。
公式イメージを使う場合は、docker pull postgres、またはDockerfile内で FROM postgres:TAG とすればOKです。
もう一点、気になるところとしては、各コンテナの起動オプションが多いのと起動順を守らないといけないところです。
これについては、docker-composeというものを使えば解決できます。次回はそれについて勉強したいと思います。
「Dockerでつくる開発環境【PostgreSQLコンテナ編】」への1件のフィードバック