Introduction
PHPのApplication(Laravel)をContainerで動かす際に一般的にはDockerfileを用いると思うが、
dependenciesの脆弱性やpackageのUpdateなので開発者が手動で治す必要が出てくるケースがあります。
Containerで動かすImageは常に最新のpackageを保つ必要があるが、開発者が一つ一つ更新するのはかなり手間がかかるしCloudNativeの観点から見るとあまり好ましくないです。
そこでApplicationをcommandでpackしてimageを作れば毎回最新のimageを使用することができ、開発者のimageの脆弱性に対するconcernを取り除けると考えLaravel のApplicationのImage生成にpackを使用することに利用可能であったため記事にしました。
Prerequisite Background
PHPの実行環境としてメジャーなものであれば以下のstackが挙げられる。
Apache + PHP
Apacheのprocess内の一部分として、php scriptの実行環境が提供されている。
Nginx + PHP
Nginxのprocessとは別にruntimeのwebserverをphp-fpmが持つ。
NginxとPHPがtcp、またはsocket接続。
Nginx / Apacheの選定基準については以下を参照してください。
参考: Nginx / Apache
Main Contents
buildpackをLaravel Projectで使用できればimageの管理を簡略化でき、
buildpackがlaravel (php) project下でimage作成に使用。
今回は以下のProviderのbuildpackを使用し検証。
Provider Name | Provider Refs | Provider Official |
Heroku | heroku/buildpacks:18 |
今回使用するstack
Nginx + PHP
設計
$ docker run -d -p 80:8080 <image-name>
と実行するとlaravelのWelcome Pageがlocalhostでaccessできるものに決定。
Introduce
Step 1: Pre Installation
Imageの作製に必要なものをinstallします。以下のものを用意してくだない。
1. Docker For Desktop
2. Pack Command
installはこちら => buildpack.io
3. Laravel
以上となります。
Step2: Installation
作業Directoryで
$ composer create-project laravel/laravel --prefer-dist sample_buildpack_laravel $ cd sample_buildpack_laravel $ composer install
を実行。
Step3: Pre Build
Image作製前にImageのconfig情報を設定する必要があります。
おもにDockerの起動時に実行されるcommandを設定する Procfile
Image内のNginxの設定を司る nginx_app.conf
Image内のphpのconfigを設定する .user.ini (php.iniと同じ働きとみなしても構いません)
また.user.iniはoptionなのでなくても構いません。
1. Procfileと起動shellの作製
Procfile
web: ./entry.sh
entry.sh
#!/bin/bash echo $ENV_SECRETS | tr ' ' '\n' > .env; php artisan cache:clear; php artisan config:clear; php artisan view:clear; $(composer config bin-dir)/heroku-php-nginx -C nginx_app.conf public/;
環境変数はimageに依存してはならないのでdocker起動時に$ENV_SECRETSにまとめて渡すようにします。
.envをそのまま使いたい場合はecho $ENV_SECRETS | tr ' ' '\n' > .env;をcomment outしてください。
2. nginx_app_confの設定
nginx_app.conf
listen 8080 default_server; location / { root /app/public; index index.php index.html; } location @rewriteapp { rewrite ^(.*)$ /index.php$1 last; }
image作成時にnginxの設定をしたい場合はこちらに記入します。port を指定しなければ毎回randomに使われるので今回はport 8080を利用しました。port 80を使いたいところですが今回のimageで使用する軽量コンテナ内で内部的にすでにつかわれているので80を避けました。詳しくはこちら
3. .user.iniの設定 (Option)
.user.iniを設定したい場合は普段、.php.iniに記述しているものを書きましょう。
.user.ini
post_max_size = 20M max_input_vars=100000 upload_max_filesize = 5M
Step4: Build
実際にimageをbuildしてみましょう。
$ pack build <image-name>:<tag> --buildpack heroku/php --buildpack heroku/nodejs --builder heroku/buildpacks:18
frontにwebpackを使用していない場合は --buildpack heroku/nodejs
を入れなくても大丈夫です。
Step5: Run
$ docker run -d -e ENV_SECRETES='DB_CONNECTION=mysql DB_HOST=127.0.0.1' -p 80:8080 --name <container-name> <image-name>:<tag>
localhostにaccessできれば完成です。お疲れさまでした。
ENV_SECRETSはか各自、好きなものを指定してください。
Conclusion
このように、pack commandを使うだけでdockerfileを書かなくてもpackageを最新に保つことができる。
packをci/cdに組み込めばかなり簡単にArtifactを抽出できる。 ためしてしてはどうでしょうか!
参考: Application Repositoryはこちら
Appendix
Listenしているportを作製されたimageのcontainerの中身を少し見てみました。
しっかりとnginxがbindされています。
ここまで、読んでいただきありがとうございました。