こんにちは皆さん
CIっていい響きですよね!
継続的インテグレーション、なんて日本語に訳すとなんのことだかわからないところもおしゃれです。
現在ポピュラーなCIサービスといえば、github連携のTravis CIじゃないかと思います。
ここは自分もおしゃれ開発の仲間入りしたい!とばかりに、Travis CIを使ってみたのですが、昔普通にphp環境で組んだことがあったので、今回はdockerを使ってしまおうと思い至ったのです。
...まあ、オシャレで優雅に見える開発も、水面下で泥臭い検証実験を繰り返しているものです。
そんなわけで、Travis CI連携して、微妙にハマったところを徒然に記していきます。
Travis CI
CI (継続的インテグレーション: continuous integration)
そもそも、継続的インテグレーションって何でしょうね。
我々の業界では、基本的には以下の意味で使用されています。
「定時になる、もしくはコミットやプッシュをトリガーとし、自動的にビルドを行う仕組み」
ビルドっていうのは、「現在のソースコードから何らかの成果を出すこと」とのことで、コンパイルして実行ファイルを出力するのもビルドであれば、テストをしてその結果を出力することもビルドの一種です。
オープンソースでは、基本的にはテストを走らせることをビルドとしていますが、自前でサービスを開発するのなら、テストしてそれが通ってからデプロイするまでの一連の行動をビルドとすることが多いと思います。
このCIですが、いろんなサービスが有ります。
- Jenkins : 自前の環境で好き勝手にカスタマイズできる定番のCIツール
- Travis CI: Githubと連携して
.travis.yml
に記載されている設定に従って、ビルドを行う。githubへのpushがトリガー - Circle CI: Githubやその他のホスティングサービスと連携して、
circl.yml
の設定に従ってビルドを行う。プライベートリポジトリに対してもCIできる
その他にもいろいろありますが、メジャーどころはこんなところでしょう。
Travis CI
大体のオープンソースプロジェクトには、ルートディレクトリに.travis.yml
があったりするため、その界隈では一番流行っているのではないかと思います。
public なリポジトリであれば、無料で利用できます。
ちょっと追加で費用はかかりますが、privateなリポジトリをビルドしてデプロイまですることができます。
ビルドのは、masterへのpushの他、Pull Requestへのpushにも適用されます。
さらに、このビルドの結果はgithubにフィードバックされます。
これにより、現在のPull Requestがビルドに成功しているか、つまりテストを通しているかどうかが可視化されるため、マージしてよいかどうかの指標として使えます。
というか、テスト通っていないコードなんて、論外とばかりに弾けばコードを見渡す手間が省けるわけです。
Travis CIの利用開始はものすごく簡単です。
まず公式サイトに行きます。
https://travis-ci.org/
で、githubアカウントでログインできるというので、ログインします。
すると、以下の様な画面になります。
。。。もうやること書いてありますね。
まず、対象のリポジトリを選択して、チェック状態にします。
更新ボタンとか押さなくても大丈夫です( そもそもないし )。
で、.travis.yml
をリポジトリに登録して、githubにpushすれば、それをトリガにしてビルドを初めます。
DockerでCIした軌跡
先日の記事においてlaravelで掲示板を作ってテストも入れてみました。
こいつをCIに登録して、オシャレ開発の仲間入りをしましょう。
Travis CIでもDockerを使用できるとのことですので、自分の環境に限りなく近い環境を、Travis上に構築できると考えて、早速使うことにしたのです。
https://docs.travis-ci.com/user/docker/
初期の.travis.yml
は以下の様な感じです
sudo: required
language: php
service: docker
before_install:
- docker-compose up -d
- docker-compose exec workspace composer install
- cp .env.example .env
- docker-compose exec workspace php artisan key:generate
script:
- docker-compose exec workspace ./vendor/bin/phpunit
ついでにdocker-compose.yml
も晒しておきます。
version: '2'
services:
workspace:
image: niisantokyo/laradock_ws
volumes:
- ./:/var/www/laravel
tty: true
mysql_test:
image: mysql
ports:
- "3306"
environment:
MYSQL_DATABASE: homestead
MYSQL_USER: homestead
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: root
docker-composeがない
以下のログを吐き出し、ビルドが止まってました。
$ docker-compose up -d
/home/travis/build.sh: line 45: docker-compose: command not found
The command "docker-compose up -d" failed and exited with 127 during .
Your build has been stopped.
コマンドが見つからないだとぉ!?
何が悪いんだと思ったけど、そもそもservice
の項目が間違っているようで、以下のようにするべきだたようです。
-service: docker
+services:
+ - docker
これで大丈夫でしょう!
docker-composeのバージョンが古いよ!
以下のエラーが出て、やっぱりビルドが止まりました。
$ docker-compose up -d
Unsupported config option for services service: 'workspace'
The command "docker-compose up -d" failed and exited with 1 during .
Your build has been stopped.
なんだこれ?
どうも、Travis上のdocker-composeが古い模様。
なんだそれ。。。
とりあえず、docker-composeのバージョンアップもさっきのtravis公式にあったので適用。
+env:
+ DOCKER_COMPOSE_VERSION: 1.8.0
+
before_install:
+ - sudo rm /usr/local/bin/docker-compose
+ - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
+ - chmod +x docker-compose
+ - sudo mv docker-compose /usr/local/bin
- docker-compose up -d
これで大丈夫でしょう。
Dockerのバージョンも古い
0.28s$ docker-compose up -d
ERROR: The Docker Engine version is less than the minimum required by Compose. Your current project requires a Docker Engine of version 1.10.0 or greater.
The command "docker-compose up -d" failed and exited with 1 during .
Your build has been stopped.
まじかよ。。。
dockerのバージョンを上げなければならない模様。
公式にはdockerのバージョンの上げ方は載っていないけど、sudoが使えるので、普通にバージョンを上げればいいはず。
dockerのバージョン上げの方法をネットで探して、適用。
before_install:
+ - sudo apt-get update
+ - sudo apt-get install docker-engine
- sudo rm /usr/local/bin/docker-compose
ビルドが終わらない
$ sudo apt-get install docker-engine
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libsystemd-journal0
The following NEW packages will be installed:
libsystemd-journal0
The following packages will be upgraded:
docker-engine
1 upgraded, 1 newly installed, 0 to remove and 287 not upgraded.
Need to get 19.4 MB of archives.
After this operation, 72.9 MB of additional disk space will be used.
Do you want to continue? [Y/n]
おっと、ここは強制yesのオプションを入れておくべきでしたね
- - sudo apt-get install docker-engine
+ - sudo apt-get install -y docker-engine
いやぁ、失敬失敬。
ささ、ビルドしましょう。
Configuration file '/etc/default/docker'
==> Modified (by you or by a script) since installation.
==> Package distributor has shipped an updated version.
What would you like to do about it ? Your options are:
Y or I : install the package maintainer's version
N or O : keep your currently-installed version
D : show the differences between the versions
Z : start a shell to examine the situation
The default action is to keep your current version.
*** docker (Y/I/N/O/D/Z) [default=N] ?
なんだこれは!?
どうも古い設定ファイルが残っているようで、こいつを残すか消すかを求められている模様。
-y
オプションつけてもダメポ。
漂浪したうえでようやく見つけたのが次のオプションが-o Dpkg::Options::="--force-confnew"
。
これをつけることで、ようやく動きました!
- sudo apt-get update
- - sudo apt-get install -y docker-engine
+ - sudo apt-get -y -q -o Dpkg::Options::="--force-confnew" install docker-engine
- sudo rm /usr/local/bin/docker-compose
動いたと思ったか!?
ビルドに失敗しました。。
Generating optimized class loader
Compiling common classes
The command "docker-compose exec workspace composer install" failed and exited with 129 during .
Your build has been stopped.
ステータスコードが129で失敗だとぉ!?
どうやらdocker exec
のステータスコードが何をやってもこのコードが返却される模様。
Docker的には「横道の処理」なので、ちゃんとdocker run
を使わなきゃダメということだろうか。。。
必要な箇所をrun
に置き換えて、
$ docker-compose run workspace ./vendor/bin/phpunit
PHPUnit 4.8.26 by Sebastian Bergmann and contributors.
........
Time: 1.17 seconds, Memory: 18.00MB
OK (8 tests, 68 assertions)
The command "docker-compose run workspace ./vendor/bin/phpunit" exited with 0.
Done. Your build exited with 0.
やったぜ!
最終的な.travis.yml
最終的には以下の様な設定に落ち着きました。
sudo: required
services:
- docker
env:
DOCKER_COMPOSE_VERSION: 1.8.0
before_install:
- sudo apt-get update
- sudo apt-get -y -q -o Dpkg::Options::="--force-confnew" install docker-engine
- sudo rm /usr/local/bin/docker-compose
- curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
- chmod +x docker-compose
- sudo mv docker-compose /usr/local/bin
- docker-compose up -d mysql_test
- docker-compose run workspace composer install
- cp .env.example .env
- docker-compose run workspace php artisan key:generate
script:
- docker-compose run workspace ./vendor/bin/phpunit
途中端折ったりもしているので、詳しく見たいという好事家の方はこちらのリポジトリをどうぞ。
https://github.com/niisan-tokyo/laravel_board
まとめ
エレガントだったりオシャレだったりっていうのは、その影に泥臭い作業があるものです。
結局何が言いたいかって言うと、「さくっと」「簡単に」「すぐに」「時間が節約できる」といった華麗な文言に惹かれて自分でやってみたら、全然そんなことないやん!ってことがよくあると思います。
しかし、それで諦めずに、ドロドロと検証を続ければ、いつかは達成できるんじゃないかと思います。
そんな感じの日記でした。