Shin x Blog

PHPをメインにWebシステムを開発してます。Webシステム開発チームの技術サポートも行っています。

CircleCI + Docker で PHP 7 と PhantomJS 使って CI する

CircleCI で、とあるプロジェクトの CI 環境を作りました。このプロジェクトは、PHP 7 で開発しているのですが、まだ CircleCI 公式では PHP 7 がサポートされていません。

f:id:shin1x1:20160216044318p:plain

そこで、Docker を使って、PHP 7 + PhantomJS 環境を構築しました。

構成

PHPUnit と Codeception のテストを実行する環境を構築します。 コンテナの構成は、下記のようになります。

  • PHP 7 コンテナ
  • PhantomJS コンテナ
  • PostgreSQL コンテナ * 2

これらのコンテナは、docker-compose でまとめて構築、実行します。

PHP 7 コンテナ

PHP 7 + Apache のコンテナです。Docker Hub オフィシャルの php:7.0-apache ベースにして、Laravel 5.1 実行に必要な拡張の追加や設定を行ったイメージ shin1x1/docker-laravel-on-php7-apache を構築しました。

https://github.com/shin1x1/docker-laravel-on-php7-apache

イメージは、Docker Hub で公開しているので、イメージ shin1x1/laravel-on-php7-apache で実行できます。

https://hub.docker.com/r/shin1x1/laravel-on-php7-apache/

$ docker run shin1x1/laravel-on-php7-apache php -v
PHP 7.0.3 (cli) (built: Feb  5 2016 18:24:39) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies

PostgreSQL コンテナ

DB に PostgreSQL を利用しているのでこちらもコンテナを用意しました。こちらはオフィシャルの postgres:9.5 をそのまま利用しています。このイメージは環境変数で幾つかのパラメータを指定できるので必要なものを設定します。

  • POSTGRES_USER - PostgreSQLユーザ
  • POSTGRES_PASSWORD - PostgreSQLユーザのパスワード
  • POSTGRES_DB - データベース名

アプリケーション動作用とユニットテスト用で二つのコンテナを構築します。

PhantomJS コンテナ

edvakf/phantomjs-japanese イメージを利用します。

docker-compose.yml

コンテナを構築・実行する docker-composer.yml は、下記です。

web が、PHP を動作させるコンテナです。アプリケーションコードはホストのものをマウントします。カレントディレクトリを /var/www/html にマウントしている箇所がそれです。

phantomjs が、PhantomJS のコンテナです。edvakf/phantomjs-japanese イメージを利用しており、4444/tcp をホスト側にマッピングしています。アクセプタンステストで web コンテナにアクセスするので links で指定しています。

db_appdb_app_test が、データベースのコンテナです。上述の通り、PostgreSQL のイメージを利用します。POSTGRES_USER が、vagrant なのは、開発環境でユーザ名をこれにしているのでそれに合わせています。それぞれのコンテナは、web コンテナから参照できるように links で指定しています。

web:
  image: shin1x1/laravel-on-php7-apache
  ports:
    - "8000:80"
  links:
    - db_app
    - db_app_test
  volumes:
    - .:/var/www/html
  environment:
    DB_HOST: db_app

phantomjs:
    image: edvakf/phantomjs-japanese
    command: --webdriver=0.0.0.0:4444
    ports:
      - "4444:4444"
    links:
      - web

db_app:
  image: postgres:9.5
  environment:
    POSTGRES_USER: vagrant
    POSTGRES_PASSWORD: pass
    POSTGRES_DB: app
    LC_ALL: C

db_app_test:
  image: postgres:9.5
  environment:
    POSTGRES_USER: vagrant
    POSTGRES_PASSWORD: pass
    POSTGRES_DB: app_test
    LC_ALL: C

circle.yml

circle.yml は、下記のようにしています。

dependencies では、docker-compose コマンドでコンテナを実行します。ただ、composer install は、キャッシュを効かすために CircleCI 上(ホスト)で実行しています。

test では、pre でアプリケーションのセットアップを行い、override で PHPUnit と Codeception でテストを実行しています。

machine:
  php:
    version: 5.6.14
  services:
    - docker

dependencies:
  override:
    - composer install --prefer-source --no-interaction --dev
    - docker-compose up -d

test:
  pre:
    - cp .env.example .env
    - docker-compose run web php artisan key:generate
    - docker-compose run web php artisan migrate
    - docker-compose run web php artisan db:seed
    - docker-compose run web php artisan db:seed --class DemoSeeder
    - sudo chmod -R a+w storage

  override:
    - docker-compose run -e DB_HOST=db_app_test web ./vendor/bin/phpunit
    - docker-compose run web ./vendor/bin/codecept run -c codeception/codeception.yml

さいごに

これまで Jenkins や Travis CI を使って CI 環境を構築してきました。

CircleCI も以前試したのですが、PHP の拡張が足りないなどやや不足感があって利用していませんでした。その当時から比べると PHP のサポートも充実してきたと思うのですが、それよりも Docker サポートによってかなりの部分をカバーできるようになりました。

なんといっても CircleCI は、SSH でログインできるのが大きなメリットで、試行錯誤の段階で大いに役立ちました。やはり、直接ログインできるのは安心感ありますね。

サーバ/インフラエンジニア養成読本 DevOps編 [Infrastructure as Code を実践するノウハウが満載! ] (Software Design plus)

サーバ/インフラエンジニア養成読本 DevOps編 [Infrastructure as Code を実践するノウハウが満載! ] (Software Design plus)