いっきのblog

技術とか色々

Docker Compose + LaravelをCircleCI2.0上でテストする

どうも、くずきです。
こないだ久々にCircleCIを使ったらバージョンが上がってたのとdocker-composeを使ったやり方が変わっていたので、とりあえずテストまでできたレベルメモっておきます。

各バージョン

  • Dokcer(for MacOS)
    • Docker version 17.03.1-ce, build c6d412e
  • docker-compose
    • docker-compose version 1.11.2, build dfed245
  • Laravel
    • 5.5.11
  • PHP
    • 7.1.1
  • Mysql
    • 5.7
  • CircleCI
    • 2.0

※ 今回アプリケーションとしてLaravel使うけど、構築などの説明はしないです。

Dockefileの設定

すでにLaravelのアプリケーションがある前提で、さっさと構築。

FROM php:7.1.1-apache
RUN a2enmod rewrite
RUN set -ex \
  && buildDeps=' \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng12-dev \
  ' \
  && apt-get update \
  && apt-get install -y --no-install-recommends \
    $buildDeps \
    libmcrypt-dev \
    libicu-dev \
    curl \
    zip \
    unzip \
  && rm -rf /var/lib/apt/lists/* \
  && docker-php-ext-configure \
    intl \
  && docker-php-ext-install \
    pdo_mysql \
    mysqli \
    mbstring \
    gd \
    iconv \
    mcrypt \
    intl \
  && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
  && apt-get purge -y --auto-remove $buildDeps

COPY php.ini /usr/local/etc/php/

Dockerfileとして、アプリケーションのルートディレクトリに配置。
目新しいことはしてない一般的なphp周りの設定。

docker-compose.ymlの設定

docker-compose.ymlを以下のように書く。

version: '2'

services:
  datastore:
    image: busybox
    volumes:
     - /var/lib/mysql
  db:
    image: mysql:5.7
    command: >
      bash -c '
      mkdir /var/log/mysql &&
      touch /var/log/mysql/general.log &&
      chown mysql:mysql /var/log/mysql/general.log &&
      tail -f /var/log/mysql/general.log &
      /entrypoint.sh mysqld
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
      --general-log=true
      --general-log-file=/var/log/mysql/general.log
      '
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD=true
      - MYSQL_DATABASE=[データベース名]
    ports:
      - "3333:3306"
    volumes_from:
      - datastore
  cache:
    image: redis:3.2.3-alpine
    ports:
      - "6379:6379"
  app:
    build: .
    ports:
      - "8000:80"
    volumes:
      - .:/var/www/html
      - ./000-default.conf:/etc/apache2/sites-available/000-default.conf
    depends_on:
      - db
      - cache

Dockerfileと同じくルートディレクトリに配置。
ここも特に目新しいことはしてないが、mysql.logを常にtailしたかったので、いらない人はその部分を消してもらえると良いです。
一応apache000-default.confも載せておく。

<VirtualHost *:80>
    DocumentRoot /var/www/html/public
    <Directory "/var/www/html/public">
            AllowOverride All
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

CircleCI用の.envファイルの設定

APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=[データベース名]
DB_USERNAME=root
DB_PASSWORD=

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=cache
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=
MAIL_FROM_NAME=
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_PRETEND=false

CircleCI用にLaravel.env.circleファイルの設定。
DB_HOSTREDIS_HOSTdocker-composeで設定した名前を書く。

CricleCIの設定

最後に、CircleCIの設定ファイルを.circleci/config.ymlに書く。

versin: 2
jobs:
  build:
    machine: true
    steps:
      - checkout
      - run:
          name: Setup docker
          command: |
            docker-compose build
            docker-compose up -d
            docker-compose run app composer install
      - run:
          name: Setup Laravel
          command: |
            cp .env.circleci .env
            docker-compose run app php artisan key:generate
            docker-compose run app php artisan migrate:refresh --seed
      - run:
          name: Run Test
          command: |
            docker-compose run app vendor/bin/phpunit

CircleCI2.0の新機能であるworkflowsを使ってないので物足りなさがあるが、これで一通り設定できた。

f:id:kzkohashi:20170929193055p:plain

CircleCIでの結果画面。

今後

今回の設定だと、そもそも毎回docker-composeをビルドするせいで遅く、キャッシュさせる必要がある。
CircleCI2.0だとsave_cacherestore_cacheを使えばできそうみたい。workflowsも含めて、次回へのお楽しみということで・・・。