ちょっとした技術メモを忘れないうちに書いていく

DockerでCakePHP3+PostgreSQL環境を構築する

2019-09-26

Docker便利!


久しぶりに Apache、PHP の開発環境の構築なので、Docker-ce を使ってみる。 Windows 7 上の VirtualBox に ubuntu18 をインストールして実施。

Docker のインストール

公式サイトの手順はこちら

プロキシ環境の場合、所々コマンドにオプションが必要だったりするのでこちらも参照

  1. パッケージリストの更新とパッケージのインストール ubuntu のターミナルで以下のコマンドを実行し、HTTPS 経由で取得できるようにする
sudo apt-get update

sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
  1. Docker の公式 GPG キーを追加する curl コマンドで GPG キーを取得し追加する。 追加されると「OK」と一言表示される。
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

追加されているかの確認のため以下のコマンドで結果が返ってくるか確かめる。

sudo apt-key fingerprint 0EBFCD88

#↓が表示される
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [  不明  ] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]
  1. Docker のリポジトリを追加する アーキテクチャが amd64 の場合以下のコマンドを実行。 ※arch コマンドを実行して、「x86_64」と表示されたら amd64 のコマンドで OK。
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

他のアーキテクチャのコマンドも公式サイトに記述されています。

  1. Docker のインストール やっとインストールコマンド。
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

ログインしている一般ユーザー権限で Docker コマンドを実行する場合は、グループに所属させる。

sudo usermod -aG docker ユーザー名

バージョンを表示して、インストールが完了していることを確認。

docker version
  1. Docker Compose のインストール WEB サーバ、DB サーバを分けて管理したいので Docker Compose もインストールする。 この時点では 1.24.1 が最新
sudo curl -L  "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

※プロキシ環境の場合 curl 実行時 -x でプロキシ情報を指定する。

バージョンを表示してインストールされていることを確認する。

docker-compose --version

CakePHP3+PostgreSQL 環境を構築

  1. WEB サーバと DB サーバの構築 プロジェクトディレクトリとして cakephp_test を作成し、以下の構成を作成する。
/cakephp_test
├── /Docker
│   ├── /php
│   │   └── Dockerfile
│   └── /postgres
│       └── /data
└── docker-compose.yml

docker-compose.yml に WEB サーバと DB サーバの設定を記述する。

docker-compose.yml
version: '3'
services:
  cakephp_web: # WEBサーバの設定
    build:
      context: .
      dockerfile: ./Docker/php/Dockerfile # Dockerfileの場所を指定
    volumes:
      - .:/var/www/html:cached # マウント設定、ホスト側の階層と、コンテナ側の/var/www/htmlをマウント
    ports:
      - "80:80" # ポートの転送設定
  cakephp_db: # DBサーバの設定
    image: postgres:10.3-alpine # DockerHubから取得したいイメージを指定
    environment: # postgresの初期設定(ユーザー名、パスワード、DB名を指定)
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: test_db
    ports:
      - 5432:5432 # ポート転送の設定 ... ホスト側ポート:コンテナ内ポート (ポー>ト番号を同じにすると起動にエラーになる)
    volumes:
      - ./postgres/data:/var/lib/postgresql/data # マウント設定、コンテナ側のpostgresqlのデータディレクトリをホスト側の./postgres/dataにマウント
Docker/php/Dockerfile
FROM php:7.2-apache

# apacheの設定
ENV APACHE_DOCUMENT_ROOT /var/www/html/app/webroot
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf \
&& sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf \
&& a2enmod rewrite

# cakephpインストール用にインストール、phpのエクステンションはdocker-php-ext-installでインストールする
RUN apt-get update && apt-get install -y \
    libicu-dev \
    zip \
    unzip \
    libpq-dev \
&& docker-php-ext-install -j$(nproc) intl \
&& docker-php-ext-install -j$(nproc) pdo_pgsql

RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

COPY . /var/www/html

# composerのインストール
ENV COMPOSER_ALLOW_SUPERUSER 1
COPY --from=composer:1.7 /usr/bin/composer /usr/bin/composer
  1. サーバの構築と起動

cakephp_test ディレクトリでコマンドを実行

docker-compose up -d

#いろいろログが流れて最終的に↓が表示される
Creating cakephp_test_cakephp_db_1  ... done
Creating cakephp_test_cakephp_web_1 ... done

コンテナの状況を確認する

docker container ls

#結果のSTATUSがupになっているので両コンテナとも立ち上がっている
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                    NAMES
6fdba9be3fee        cakephp_test_cakephp_web   "docker-php-entrypoi…"   2 minutes ago       Up 2 minutes        0.0.0.0:80->80/tcp       cakephp_test_cakephp_web_1
159bb4c4d9df        postgres:10.3-alpine       "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes        0.0.0.0:5432->5432/tcp   cakephp_test_cakephp_db_1
  1. DB サーバの接続確認 HOST 側のとごろな SQL クライアントから接続確認を行う。 接続情報には docker-compose.yml で設定したユーザー名、パスワード、DB 名を指定

cakephp_docker_1.png

接続後、test_db が作成されていることを確認する(テーブルはまだない)。

cakephp_docker_2.png

  1. WEB サーバの接続確認 ブラウザから「http://localhost/」へアクセスする。

cakephp_docker_3.png

ページが何もないのでエラーが表示されるが、Apache が応答を返していることが確認できる。

CakePHP3 のインストール

WEB サーバの構築が完了したので CakePHP3 のインストールを行う。

  1. WEB サーバにログインする

以下のコマンドで WEB サーバのコンテナ側にログインして操作ができる。 ホスト側に戻るには「Ctrl」を押しながら「p」「q」を押す。

docker exec -it cakephp_test_cakephp_web_1 bash

cakephp_test_cakephp_web_1 の所には「docker container ls」の結果の NAME の値を指定する。 「docker exec」自体はコンテナにコマンドを投げるだけなので、「-it」をつけることでログインし続けることができる。

  1. CakePHP3 のインストール

Composer はすでにインストール済みなので Composer コマンドを利用する。

composer create-project --prefer-dist cakephp/app:3.8.* ./app

# 途中でPermission設定するかどうか聞かれるので「Y」をこたえる
Set Folder Permissions ? (Default to Y) [Y,n]? Y

※メモ create-project の内容は git clone と同じ(らしい)。 —prefer-dist をつけるとソースを zip で取得するので早い(らしい)。

再度、「http://localhost/」へアクセスする。 相変わらずエラーとなっているが、CakePHP3 の MySQL 接続エラーに変わっていることが確認できる。

cakephp_docker_4.png

インストールが完了するとディレクトリ構成に app が追加される。

/cakephp_test
├── /Docker
│   ├── /php
│   │   └── Dockerfile
│   └── /postgres
│       └── /data
├── /app
└── docker-compose.yml
  1. CakePHP3 の DB 設定の変更

デフォルトでは MySQL への接続となっているため、今回の構成用に修正する。 ホスト側から手頃なエディターで config/app.php を開き、Datasources の「default」と「test」の内容を修正する。

  • driver:Mysql::class → Cake\Database\Driver\Postgres
  • host:localhost → cakephp_test_cakephp_db_1
  • username:my_app → postgres
  • password:secret → password
  • database:my_app → test_db
config/app.php
    'Datasources' => [
        'default' => [
            'className' => Connection::class,
            'driver' => 'Cake\Database\Driver\Postgres',
            'persistent' => false,
            'host' => 'cakephp_test_cakephp_db_1',
            /*
             * CakePHP will use the default DB port based on the driver selected
             * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
             * the following line and set the port accordingly
             */
            //'port' => 'non_standard_port_number',
            'username' => 'postgres',
            'password' => 'password',
            'database' => 'test_db',
            /*
             * You do not need to set this flag to use full utf-8 encoding (internal default since CakePHP 3.6).
             */
            //'encoding' => 'utf8mb4',
            'timezone' => 'UTC',
            'flags' => [],
            'cacheMetadata' => true,
            'log' => false,

            /**
             * Set identifier quoting to true if you are using reserved words or
             * special characters in your table or column names. Enabling this
             * setting will result in queries built using the Query Builder having
             * identifiers quoted when creating SQL. It should be noted that this
             * decreases performance because each query needs to be traversed and
             * manipulated before being executed.
             */
            'quoteIdentifiers' => false,

            /**
             * During development, if using MySQL < 5.6, uncommenting the
             * following line could boost the speed at which schema metadata is
             * fetched from the database. It can also be set directly with the
             * mysql configuration directive 'innodb_stats_on_metadata = 0'
             * which is the recommended value in production environments
             */
            //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],

            'url' => env('DATABASE_URL', null),
        ],

        /**
         * The test connection is used during the test suite.
         */
        'test' => [
            'className' => Connection::class,
            'driver' => 'Cake\Database\Driver\Postgres',
            'persistent' => false,
            'host' => 'cakephp_test_cakephp_db_1',
            //'port' => 'non_standard_port_number',
            'username' => 'postgres',
            'password' => 'password',
            'database' => 'test_db',
            //'encoding' => 'utf8mb4',
            'timezone' => 'UTC',
            'cacheMetadata' => true,
            'quoteIdentifiers' => false,
            'log' => false,
            //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
            'url' => env('DATABASE_TEST_URL', null),
        ],
    ],

「localhost」の CakePHP の Welcome ページが表示され、Database がコネクトされていることが確認できる。

cakephp_docker_5.png

本当に動いているか確認

ちょっとした入力フォームを作成し、動作確認を行う。

  1. テスト用のテーブルを作成する。

入力情報を入れるテーブルを作成する。

CREATE TABLE records (
	id serial NOT NULL,
	name varchar(16) NOT NULL,
	created timestamp NOT NULL,
	modified timestamp NOT NULL,
	CONSTRAINT records_pkey PRIMARY KEY (id)
);
  1. テーブルからコントローラー一式を作成する。

コンテナ側で CakePHP3 インストールディレクトリの bin/cake を実行し、records からコントローラー一式を作成する。

./app/bin/cake bake all records

モデル系、コントローラー、テンプレート系が作成される

  • src/Model/Table/RecordsTable.php
  • src/Model/Entity/Record.php
  • src/Controller/RecordsController.php
  • src/Template/Records/index.ctp
  • src/Template/Records/view.ctp
  • src/Template/Records/add.ctp
  • src/Template/Records/edit.ctp

http://localhost/Records」にアクセスすると一覧画面が表示される。

cakephp_docker_6.png

  1. データの登録を行い、テーブルに登録されることを確認する。

一覧画面の左メニューの「New Record」から新規登録画面遷移する。

cakephp_docker_7.png

登録後、DB のテーブルを確認し、データが登録されていることを確認する。

cakephp_docker_8.png