データベースをセットアップする

データベースをセットアップする

カンファレンスゲストブックの Webサイトでは、カンファレンス中のフィードバックを集めるようにします。カンファレンスの参加者からのコメントを永続的に格納できるようにする必要があります。

コメントは、次のデータ構造を持っています: author(著者), email(メールアドレス), text(フィードバックのテキスト), photo(オプショナルの写真)。これらのデータは、リレーショナルデータベースに格納するのに向いています。

今回は、 PostgreSQLをデータベースエンジンとして使います。

Docker Compose へ PostgreSQL を追加

私たちのローカル開発環境には、Docker を用いてサービスを運用するようにしています。自動生成された docker-compose.yml ファイルには既に PostgreSQL がサービスとして追加されています:

docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
###> doctrine/doctrine-bundle ###
database:
    image: postgres:${POSTGRES_VERSION:-13}-alpine
    environment:
    POSTGRES_DB: ${POSTGRES_DB:-app}
    # You should definitely change the password in production
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ChangeMe}
    POSTGRES_USER: ${POSTGRES_USER:-symfony}
volumes:
    - db-data:/var/lib/postgresql/data:rw
    # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
    # - ./docker/db/data:/var/lib/postgresql/data:rw
###< doctrine/doctrine-bundle ###

PostgreSQL サーバをインストールし、データベース名やクレデンシャルを制御するための環境変数を設定します。値にこだわりはありません。

また、ローカルホストへ PostgreSQL のポート(5432)を公開します。これで自分の開発環境からデータベースへ接続できるようになります:

docker-compose.override.yml
1
2
3
4
5
###> doctrine/doctrine-bundle ###
database:
    ports:
    - "5432"
###< doctrine/doctrine-bundle ###

Note

pdo_pgsql 拡張は、PHP をセットアップした前のステップでインストールされているはずです。

Docker Compose を起動しましょう

Docker Compose をバックグラウンドで起動します (-d):

1
$ docker-compose up -d

データベースが起動するのを待って、すべて正しく動いているかチェックしましょう:

1
2
3
4
5
$ docker-compose ps

        Name                      Command              State            Ports
---------------------------------------------------------------------------------------
guestbook_database_1   docker-entrypoint.sh postgres   Up      0.0.0.0:32780->5432/tcp

もしコンテナが起動していなかったり、 State カラムが Up になっていなければ、 Docker Compose のログをチェックしましょう:

1
$ docker-compose logs

ローカルのデータベースへのアクセス

psql コマンドラインを使用することが便利なときもあります。しかし、データベース名やクレデンシャルを覚えておく必要があります。また、ホスト上で動いているデータベースのローカルポートも知る必要があります。Docker は、同時に PostgreSQL を使用するプロジェクトが一つ以上あったときでも動くようにランダムなポートを選択します(ローカルポートは docker-compose ps コマンドで出力できます)。

Symfony CLI で psql を実行する際は、何も覚えておく必要はありません。

Symfony CLI は自動的にプロジェクトで実行されている Docker サービスを検知し、 psql コマンドで必要になるデータベース接続に関する環境変数を公開します。

この規約があるので、 symfony run を使ってデータベースに接続することがより簡単になるのです:

1
$ symfony run psql

Note

あなたのローカル開発環境に psql バイナリがないときは、 docker-compose を介して実行することも可能です:

1
$ docker-compose exec database psql main main

データベースのダンプとリストア

pg_dump コマンドを使ってデータベースのデータをダンプします:

1
$ symfony run pg_dump --data-only > dump.sql

そして、データをリストアします:

1
$ symfony run psql < dump.sql

PostgreSQL を Platform.sh へ追加

Platform.sh の本番インフラでは、PostgreSQL のようなサービスを追加する際に、.platform/services.yaml ファイルを使用しますが、 webapp パッケージのレシピで既に追加されています:

.platform/services.yaml
1
2
3
database:
    type: postgresql:13
    disk: 1024

database サービスは PostgreSQL データベース (Dockerと同じバージョン) で、ディスク 1GB のコンテナをプロビジョニングする必要があります。

また、アプリケーションコンテナと DB を "リンク" する必要があります。これは、 .platform.app.yaml に記述されます:

.platform.app.yaml
1
2
relationships:
    database: "database:postgresql"

postgresqldatabase サービスは、アプリケーションコンテナでは、 database と参照されます。

pdo_pgsql 拡張がPHP ランタイムに追加されていることを確認しましょう:

.platform.app.yaml
1
2
3
4
5
runtime:
    extensions:
        # other extensions
        - pdo_pgsql
        # other extensions

Platform.sh のデータベースへのアクセス

PostgreSQL が Docker 経由のローカルと、 Platform.sh の本番で動いています。

ここで見たように、 symfony run コマンドで環境変数が公開されているので、 symfony run psql を実行すると Docker によってホストされているデータベースに自動的に接続することができます。

本番のコンテナ上の PostgreSQL に接続したければ、ローカル環境と Platform.sh の間で SSH トンネルを開く事が可能です:

1
2
$ symfony cloud:tunnel:open
$ symfony var:expose-from-tunnel

デフォルトでは、 Platform.sh のサービスは、ローカル環境に環境変数を公開していません。 var:expose-from-tunnel コマンドを実行して明示する必要があります。本番のデータベースに接続するのは、危険な運用だからです。本当の データを壊してしまうかもしれません。フラグを必須とすることで、あなたがしようとしていることの確認をしているのです。

今度は、前のように symfony run psql 経由でリモートの PostgreSQL データベースへ接続しましょう:

1
$ symfony run psql

接続が終わったら、トンネルをクローズするのを忘れないでください:

1
$ symfony cloud:tunnel:close

Tip

Shell の代わりに本番のデータベース上で SQL を実行するのに symfony sql コマンドも使用することができます。

環境変数を公開する

環境変数を使うことで、Docker Compose と Platform.sh はシームレスに Symfony と連携することができます。

symfony var:export を実行して symfony が公開している全ての環境変数をチェックしてみましょう:

1
2
3
4
5
6
7
8
$ symfony var:export

PGHOST=127.0.0.1
PGPORT=32781
PGDATABASE=main
PGUSER=main
PGPASSWORD=main
# ...

PG* 環境変数は psql ユーティリティで使われます。他はどうでしょうか?

var:expose-from-tunnel コマンドを実行して、 Platform.sh へのトンネルをオープンすると、 var:export コマンドは、リモートの環境変数を返します:

1
2
3
4
$ symfony cloud:tunnel:open
$ symfony var:expose-from-tunnel
$ symfony var:export
$ symfony cloud:tunnel:close

インフラストラクチャ情報を記述する

まだ気づいていないかもしれませんが、インフラストラクチャ情報をコードと一緒にファイルに保存することは、非常に役に立ちます。DockerやPlatform.shは設定ファイルを使って、プロジェクトのインフラストラクチャ情報を記述します。新しい機能でサービスの追加が必要な場合、同じパッチで、コードとインフラストラクチャを変更することができます。

This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.