Successfully reported this slideshow.
Your SlideShare is downloading. ×

Docker friendly PHP / Laravel

Ad

Docker friendly
PHP / Laravel
Laravel.shibuya #11 Online

Ad

なぜDockerを使うのか
• 軽量・高速
• 環境を選ばずどこでも動く
• ミュータブル / いつでも増やせる捨てられる
Laravel.shibuya #11 Online

Ad

現実は…
• 神Dockerfile(開発用のパッケージやツールが全部入り)
• 秘伝のタレ化したDockerfile(メンテナ退職・誰も触れない)
• 肥大化したコンテナイメージ
• 開発用と本番用とでDockerfileを二重管理
• 本番...

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Loading in …3
×

Check these out next

1 of 22 Ad
1 of 22 Ad
Advertisement

Docker friendly PHP / Laravel

  1. 1. Docker friendly PHP / Laravel Laravel.shibuya #11 Online
  2. 2. なぜDockerを使うのか • 軽量・高速 • 環境を選ばずどこでも動く • ミュータブル / いつでも増やせる捨てられる Laravel.shibuya #11 Online
  3. 3. 現実は… • 神Dockerfile(開発用のパッケージやツールが全部入り) • 秘伝のタレ化したDockerfile(メンテナ退職・誰も触れない) • 肥大化したコンテナイメージ • 開発用と本番用とでDockerfileを二重管理 • 本番環境のみ発生する不具合 • 開発環境で試せない機能 • 特定のホスト上でしか動作しないコンテナ • 更新されていない「環境構築手順書」 Laravel.shibuya #11 Online
  4. 4. PHPのDocker環境は難しい Laravel.shibuya #11 Online
  5. 5. Dockerfile Next.js vs Laravel Sail Laravel.shibuya #11 Online https://github.com/laravel/sail/blob/v1.13.5/runtimes/8.1/Dockerfile#L15-L33 https://github.com/vercel/next.js/blob/v12.1.0/examples/with-docker/Dockerfile#L1-L4 Install Node.js Install PHP
  6. 6. PHPアプリのコンテナに求められる機能 • PHP extensions / PECL extensions • それらをビルドするためのパッケージ • php-fpm / httpd or nginx • composer • データベース、メール、…等の外部接続要件 • xdebug / pcov / その他、開発ツール Laravel.shibuya #11 Online
  7. 7. マルチステージビルドでの本番イメージ作成 Laravel.shibuya #11 Online https://gist.github.com/KentarouTakeda/2d86c2d13da51610ffe6ea9f0bacee36 FROM php:8.1-fpm-alpine as base RUN apk add --no-cache autoconf g++ gcc libzip libzip-dev make postgresql postgresql-dev zlib zlib-dev && docker-php-ext-install bcmath opcache pdo pdo_pgsql zip && apk del autoconf g++ gcc libzip-dev make zlib-dev && curl -qs -o /usr/local/bin/composer https://getcomposer.org/download/latest-2.x/composer.phar && chmod +x /usr/local/bin/composer FROM base as development RUN apk add --no-cache autoconf g++ gcc make && pecl install pcov xdebug && docker-php-ext-enable pcov xdebug && apk del autoconf g++ gcc make FROM base as deploy COPY ["composer.json", "composer.lock", "./"] RUN composer install --no-dev COPY . . ①phpイメージよりbaseイメージを作成 ②baseイメージよりdeployイメージを作成 baseイメージよりdevelopmentイメージを作成 (どこからも参照されない)
  8. 8. マルチステージビルドとDocker Compose Laravel.shibuya #11 Online FROM php:8.1-fpm-alpine as base RUN apk add --no-cache autoconf g++ gcc libzip libzip-dev make postgresql postgresql-dev zlib zlib-dev && docker-php-ext-install bcmath opcache pdo pdo_pgsql zip && apk del autoconf g++ gcc libzip-dev make zlib-dev && curl -qs -o /usr/local/bin/composer https://getcomposer.org/download/latest-2.x/composer.phar && chmod +x /usr/local/bin/composer FROM base as development RUN apk add --no-cache autoconf g++ gcc make && pecl install pcov xdebug && docker-php-ext-enable pcov xdebug && apk del autoconf g++ gcc make FROM base as deploy COPY ["composer.json", "composer.lock", "./"] RUN composer install --no-dev COPY . . https://gist.github.com/KentarouTakeda/8442a591419b8f8f7302395335796a39 version: "3" services: php: build: context: . target: development volumes: - .:/var/www/html - vendor:/var/www/html/vendor volumes: vendor:
  9. 9. アプリケーションの汎用性 Laravel.shibuya #11 Online
  10. 10. 環境に依存するリソース • データベース • メール • キャッシュ • ストレージ • キュー • タスクスケジュール • ログ これら全てが「環境構築」の対象となる Laravel.shibuya #11 Online
  11. 11. Laravel 構成管理 ベストプラクティス .env を使わない config/ はデフォルトを維持 Laravel.shibuya #11 Online
  12. 12. よくある環境構築手順書 1. リポジトリをcloneします 2. docker compose up と入力します 3. docker compose exec php sh と入力しコンテナに入ります 4. composer install と入力します 5. .env.example を .env というファイル名でコピーします 6. .env を次の通り編集します ←だいたいここで詰まる • foo bar baz ... • hoge fuga piyo ... 7. localhost:8000 にアクセスします Laravel.shibuya #11 Online
  13. 13. .envはメンテされない • 追加した新機能の設定 .env.example に追記し忘れるケース • 追加した本人の.envには設定が存在するため追記忘れに気づかない • ドキュメント(構築手順書)の更新を忘れるケース • .envが存在する = 開発者の間での環境差異を許容している • 環境の再現性を求めてDockerを使い始めたのでは? • ドキュメント化出来るのであればコード化できるはず • 怠惰(Laziness)はプログラマーの美徳 Laravel.shibuya #11 Online
  14. 14. .env を使わない • ホストから環境変数を注入 • Dockerベストプラクティス • 本番環境と同じ設計 • APP_KEYのcommitが可能 • 32バイトの文字列なら何でも良い • ローカル環境でしか使われない • 暗号化・復号を環境間で再現可能 • アプリと同じリポジトリで管理 • .envが無くてもアプリが動く Laravel.shibuya #11 Online https://gist.github.com/KentarouTakeda/5fbdbcaaff3ba3945758da6659c59aff version: "3" services: php: environment: - APP_DEBUG=${APP_DEBUG:-true} - APP_KEY=${APP_KEY:-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX} - APP_ENV=local - APP_URL=http://localhost:8000 # .... build: context: . target: development volumes: - .:/var/www/html - vendor:/var/www/html/vendor volumes: vendor:
  15. 15. config/ はデフォルトを維持 • 上記は汎用性を一撃で失う例 • 環境変数から制御すればいい。 • docker-compose.ymlでの制御がおすすめ。 • laravel/laravel のconfig/は大抵の要件に対応できる(例外あり) • 「環境変数 → どうしても無理ならconfig → それも無理なら実装で対応」という順序 • config/修正の要否はアプリの疎結合を図る一つの指標 Laravel.shibuya #11 Online diff --git a/config/filesystems.php b/config/filesystems.php index cf5abce7..b76aae49 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -13,7 +13,7 @@ | */ - 'default' => env('FILESYSTEM_DISK', 'local'), + 'default' => env('s3'), /* |--------------------------------------------------------------------------
  16. 16. ログ要件 • 開発環境 • storage/logs/laravel.log に出力 • 本番環境 • コンテナ外の永続化された領域に保存しなければならない • コンテナが並列化されていたとしてもログは集約すべき • ログ管理やアラートの要件を満たしやすい形式とすべき • ログ要件(インフラ側の責務)はアプリケーションは関知すべきでない Laravel.shibuya #11 Online
  17. 17. Dockerのログ機能 • ログは標準出力へ出力 Laravel.shibuya #11 Online http://docs.docker.jp/v19.03/config/container/logging/index.html https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/using_awslogs.html
  18. 18. パブリッククラウドでのログサービス • ログの形式はjson Laravel.shibuya #11 Online https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData-discoverable-fields.html#CWL_AnalyzeLogData-discoverable-JSON-logs https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html#metric-filter-examples
  19. 19. 環境変数によるログ制御 • 本番コンテナの環境変数 • アプリケーション側は Log::info() / Log::xxxx() のみ • class AppFormatter extends JsonFormatter を作成しても良い Ref. Monolog Laravel.shibuya #11 Online https://github.com/laravel/laravel/blob/v9.0.0/config/logging.php#L89-L97 version: "3" services: php: environment: - LOG_CHANNEL=stderr - LOG_STDERR_FORMATTER=MonologFormatterJsonFormatter # ...
  20. 20. CloudWatch Logsとの親和性 CloudWatch LogsでWARNINGレベル以上のみフィルタする条件式 { $.level >= 300 } Laravel.shibuya #11 Online https://github.com/Seldaek/monolog/blob/main/doc/01-usage.md
  21. 21. キュー / タスクスケジュール • php-fpmと同じイメージ / 別のコンテナ • 専用イメージを作成しても良い(メンテコストと相談) • 起動コマンドとしてキューワーカやタスクスケジューラを指定 • CMD ./artisan schedule:work / CMD ./artisan queue:work • 基本的に全てのタスクに onOneServer() を付与 Ref.@mpyw • タスク消化が追いつかなくなったらコンテナを増やして解決 • メモリリーク等でワーカーが異常終了しても自動的に復活 • 再起動所要時間が許容できない場合 CMD で無限ループ Laravel.shibuya #11 Online
  22. 22. ストレージ • Fileファサードは使わない • 開発環境では問題なく 動いてしまう • FILESYSTEM_DISK=local は Storage を代替 出来てしまう • Storageファサードのみの動作であれば環境を問わず動く • Storage::url() / Storage::temporaryUrl() • S3とそれ以外とで動作が異なる • ドライバに応じた個別の実装がアプリ側に必要になる • ルーティングはインフラ(ロードバランサーやCDN)で解決 config(‘filesystems.disks.public’) と同じルーティングをCDNに設定する構成がおすすめ • 認可はアプリケーション側の実装で解決 • 単一の環境から複数のストレージを扱わない • 複数必要な場合コンテナを分割し各コンテナの AWS_BUCKET 環境変数で制御 • config/filesystems.phpのデフォルトを維持 • S3へのアクセス権限はKEY/SECRETではなくタスクロールで制御する • ローカル環境からはS3は扱わない。MinIOも使わない。 Laravel.shibuya #11 Online

×