ディレクトリ構成をミスってしまったアプリケーションでCircleCIを導入するのにだいぶハマってしまったので、メモとして残します。
環境情報
- PHP 7.2
- Larave l5.6
- Github
- CircleCI 2.0
- mysql 5.7
アプリケーションのディレクトリ構成
このアプリケーションを作る際に、初めてLaravelをDockerを使って環境構築をしたため、2つネストの深いディレクトリ構成で作ってしまった。この構成がおかしいと気付いた時には、時すでに遅し。気持ち悪いが、特に不便なこともなかったので、この形で進めましたた。
app
|-.circleci
├─ src
├─ hogehuga
└─ app
└─ artisan
└─ vendor
└─ tests
└─ phpunit.xml
└─ composer.json
└─ composer.lock
問題
CIでテストを自動で実行できるようにしたいと考え、GithubとCircleCIを連携させて初期状態の.circleci/config.yml
ファイルを作ってCIを動かすところまでは、簡単だった。。。
ファイルの中身は下のドキュメント通りのもの。
言語ガイド:PHP - CircleCI
ドキュメントではこれで一旦、ビルドすれば成功すると書かれているのだが、エラーが。
#!/bin/bash -eo pipefail
composer install -n --prefer-dist
Composer could not find a composer.json file in /home/circleci/project
To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section
Exited with code 1
composerがないと怒られる。原因を調べるべく、本当にcomposerがないのか、ビルドの中で、ls
コマンドを実行させてみると、projectという文字が出てくる。ここで、Laravelのディレクトリが1つ階層下にあるという構造がエラーの原因だとわかる。
run: ls
###### lsの実行結果 #####
hogehuga
解決作
- 設定しているパスを全て2つ階層を掘り下げて設定する。(./src/project/の追加)
一見、簡単な解決策なのだが、地味に大変だったので細かく解決策をここに記します。
composer
composerの実行は--working-dir
で指定可能。
composer.lock
が存在するディレクトリを設定する
- restore_cache:
keys:
- v1-dependencies-{{ checksum "./src/hogehuga/composer.lock" }}
- v1-dependencies-
- run: composer install -n --prefer-dist --working-dir=./src/hogehuga
- save_cache:
key: v1-dependencies-{{ checksum "./src/hogehuga/composer.lock" }}
paths:
- ./src/hogehuga/vendor
yarn
yarn installに関しては、--cwd
オプションでディレクトリを指定できる。
- restore_cache:
keys:
- node-v1-{{ checksum "./src/hogehuga/yarn.lock" }}
- node-v1-
- run: yarn install --cwd ./src/hogehuga
- save_cache:
key: node-v1-{{ checksum "./src/hogehuga/yarn.lock" }}
paths:
- ./src/hogehuga/node_modules
phpunit
artisan
コマンドもパスを指定して実行しなければならない。。。
phpunitもphpunit.xml
が存在しないディレクトリから実行する場合はphpunit.xml
までパスを指定しないとテストを実行することができないので、注意。
- run: php ./src/hogehuga/artisan --env=testing
- run: php ./src/hogehuga/vendor/bin/phpunit --configuration=./src/hogehuga/phpunit.xml
その他、ハマったところ
mysqlに接続できない
[Illuminate\Database\QueryException]
could not find driver (SQL: select * from sqlite_master where type = 'table ' and name = migrations)
[Doctrine\DBAL\Driver\PDOException]
could not find driver
[PDOException]
could not find driver
これは、ドキュメントだとデータベースをsqliteを使っている為、起きる。MySQLの場合は、pdo_mysql
をインストールしないといけない。
build:
# 中略
steps:
- checkout
- run: sudo apt update
- run: sudo docker-php-ext-install zip pdo_mysql
- run: sudo composer self-update
mysqlに接続できない2
In Connection.php line 664:
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name o
r service not known (SQL: SHOW FULL TABLES WHERE table_type = 'BASE TABLE')
In Connector.php line 70:
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name o
r service not known
In Connector.php line 70:
PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name or s
ervice not known
Exited with code 1
こいつは、DBのHOST設定が間違っている。dockerで開発環境を構築する際、DB_HOSTのあたいはDBコンテナ名に揃えると思うのだが、CIで実行するときはローカルホスト127.0.0.1
で設定しないといけない。
DB_CONNECTION=mysql
DB_HOST=mysql
.env.testingファイルを書き換えても良いが、そうすると自分のPC上でテスト実行したい時にエラーになってしまうので、ciのcofigファイルで設定してあげる。
build:
docker:
- image: circleci/php:7.2-node-browsers
- image: circleci/mysql:5.7
environment:
- MYSQL_DATABASE: hogehuga_testing
- MYSQL_ROOT_PASSWORD: password
environment:
- DB_HOST: 127.0.0.1
↑ ちなみに、CIで使用するmysqlイメージはcircleciが用意してくれているものを使うと最適化されていてビルドにかかる時間が短縮されるらしい。
終わりに
そもそも、ディレクトリ構造がおかしいまま開発は進めてはいけない。
参照
リポジトリ直下にcomposer.jsonがない場合でCircleCIでハマったこと - Qiita
DockerでPHPエラー「php_network_getaddresses: getaddrinfo failed: Name or service not known」
CircleCI 2.0でMySQLのイメージを使うならば、CircleCIが配布しているイメージを使わないと損 - Qiita