学習ナレッジ#2開発効率向上のための検証「開発環境整備(WSL+AmazonLinux2+Docker)」
まえがき
半年ほど前にAWSクラウドを意識してのDocker/コンテナ環境整備を行いました。
以前作成した環境に関するナレッジは以下よりご欄ください
学習ナレッジ#1知識習得を楽しめるプロを目標に「WindowsでAWSクラウドを意識したLinux/Docker学習」
以前、作成した環境を用いて数か月ほどPHPの独自フレームワークのコード整理等を行っております。
概ね、AWSクラウド上で稼働させるLinuxを意識した作りのためWindowsOSでは起こりえないような不具合などを見つけることが出来ました。
さて、Docker/コンテナを利用した開発のあれこれ学習するのは個人レベルのみとなっていますが・・・
それでも案件によっては利用する可能性もないとは言えないので検証を兼ねて、もうひと環境構築することにしました。
諸注意
本ナレッジは外部サイトのリンクを記載しています。
各リンク先のウェブサイトの内容は更新・変更により本ナレッジ作成時点とは異なる場合があります。
なお、英語のウェブサイトも含まれます。
もし英語が苦手であっても読み解く力をつけましょう。
私の経験上、日本語よりも英語のサイトの方が情報量がかなり豊富です。
なぜ検証・再構築することにしたのか?
検証・再構築の理由は主に以下の通りです。
- WindowsとLinuxをまたぐMountによるファイルアクセスが遅い
- VSCodeのWSLリモート接続について検証したくなった
- とある方から「WSLリモートのXDebugが重いという理由で採用をしなかった」という情報をもらって"重い"という点がなぜか疑問に思ったため
特に#1のファイルアクセスが重いというのは前々から気になっていました。
それでも使い始めは独自フレームワークのコード整理がメインだったのでさほど影響はありませんでした。
ですが、これから本実装を進めるにあたりやはり気になり始めました。
ざっと見積もってもWindows上でnginx+php-fpm+mariadb+redisの組み合わせで実行していた時の10~20倍近く掛かりました。
この速度問題をどこまで改善できるかが今回の焦点です。
新Docker/コンテナ開発環境概要図
今回の色々と検証した結果、Docker/コンテナ環境は以下のようになりました。
大きく違うのは、画像の赤枠(赤矢印)の箇所です。
旧環境は共有ディレクトリ(Dockerのバインドボリュームによる永続化したもの)の元がWindows側にありました。
元々、Windowsのみで開発していたのでその時のソースコードをそのまま共有化させることでWindow/Linuxのどちらでも参照できるメリットがあったからです。
新環境構築で試したこと
- WSLリモートを使用しVSCodeのワークスペース(*.code-workspace)をLinuxサイドへ配置
- Dockerのpullコマンドで取得可能な汎用イメージを極力採用
- Docker Desktop (Windows)の廃止
- 便利コマンドのシェルスクリプト化
- XDebugはDocker本体のあるLinuxで利用
- 仮想ハードディスク(*.vhdx)の省サイズ化
- PHP実行速度の検証
普段利用しているアプリ以外の導入は特にないのでDocker周りの検証がほとんどです。
Docker Desktopを廃止したのでよく使うコマンドはシェルスクリプトにして極力コマンドの入力ミスを減らすように対応しています。
後はWSLリモートやXDebugの動作検証に仮想環境を運びやすくするために小さくしたりといったことをしました。
Dockerのpullコマンドで取得可能な汎用イメージを極力採用
php-fpmもできれば汎用イメージから構成を作りたかったのですがやめました。
想定以上にインストールしなくてはならないものが多くて検証時間が掛かることが判明したのであきらめました。(時間かけても代替案があるので得られるものが少ない)
AWSクラウドで動作させるのであればDocker Hub公式のAmazonLinux:2を土台にしてもさほど問題はないだろうという判断です。
最終的にはS3・EC2・SNSなどphpからAWS関連の操作を行うことが多くなります。
この点からもAmazon系コンテナの方が検証もしやすいのではないかと推測しているが細かなところは把握していない。
何よりPHPの拡張機能のインストールが1行にすっきりまとめられるのでとても見やすく管理しやすいです。
RUN yum -y install php81-php php81-php-{fpm,gd,mbstring,mysqlnd,xml,json,openssl,opcache,exif,bcmath,pecl-redis,pecl-xdebug3}
Docker管理プロジェクトの作成(Docker Desktop廃止とコマンドのシェルスクリプト化)
企業向けに有料であるDocker Desktopを使用しなくてもやりたいことはできます。
Docker Desktopで触っていたのはコンテナの監視と起動・停止・ログ監視などでした。
ちょっとしたシェルスクリプトを組んでしまえば後はVSCodeのエクスプローラからドラッグアンドドロップ+Enterで即座に実行できます。
作成したシェルスクリプトは主に以下の用途の物です。
- ビルドスクリプト(こちらを実行すればDockerFileに基づいて環境構築される)
- 各コンテナ別のbash実行用スクリプト
- 各コンテナ別のDocker ログ取得スクリプト
- セットアップ用スクリプト(共有ネットワークやパーミッション設定)
- DockerのImage/Container/System/Builderなどのデータ削除スクリプト(HDD容量削減・ゴミ削除など)
XDebugはDocker本体のあるLinuxで利用
Docker本体を持つ仮想ハードディスクで稼働するLinuxシステムはAmazonLinux2022です。
AWSが提供している以下のセットアップの説明を元に構築しました。
Developing on Amazon Linux 2 using Windows
開発環境概要図に記載の通り、Dockerで動作するコンテナ内のphp-fpm+xdeubgからWSLリモートで接続したVSCodeでデバッグを行えるようにしています。
Google Chrome ExtensionのXdebug Helperと組み合わせることでURLにアクセスしたタイミングでVSCodeにてデバッグが行えています。
以下の画像はシンプルなものですが、コールスタック・ローカル変数・スーパーグローバル変数などデバッグ効率が格段に上がります。
動作速度について、体感としてはWindows上のみでphp-fpmでXDebugを用いて開発していた時と差はなさそうです。
小耳に挟んだWSLリモートのXdebugが重いという情報はどういった環境で発生したのか・・・気になりますね。
仮想ハードディスク(*.vhdx)の省サイズ化
AmazonLinux2022は初期起動時のVHDXのサイズが300MBくらいです。
そこからあれこれセットアップしてコンテナの起動まで行うと大体4GBまで大きくなります。
VHDXは圧縮したりできますが、どうしてもDockerやWSL周りのドライバーデータの参照などが合わさると頑張っても3GBくらいまでしか小さくできないです。
最終的にはDocker/コンテナをビルドするタイミングを後回しにすることで大体1GBまで調整が可能でした。
これくらいであればUSBメモリ等に入れて運ぶのも気軽にできそうです。
PHP実行速度の検証
私が利用しているオリジナルフレームワークのため見難いかと思いますがご了承ください。
以下の画像の通り、最小限のフレームワーク・エンジンの初期化を行ってVuetifyの枠を表示するだけのページでテストしました。
WindowsディレクトリをDockerバインドボリュームで共有した場合の実行速度
平均して1秒以上も画面表示されるまでの待ち時間が発生しており回数を重ねることを考えると開発効率は良くないと言えます。
PHPファイルの読み込みが1秒近く掛かっており、その他の処理も全体的に重たいという結果です。
LinuxディレクトリをDockerバインドボリュームで共有した場合の実行速度
結果は一目瞭然でページアクセスからページが表示されるまでの待ち時間も”待っているという”感覚がなくなりました。
RedisやMariaDBへの接続なども行われていますがざっと計算しても70倍近くの速度が出ることがわかりました。
SSD NVMeなので差は小さい方であったかもしれませんがHDDだと・・・怖いですね。
私の仕事は開発効率を常に考える現場なので怖いという感覚は少ない方の方が多いのかもしれませんが、どうでしょうか。
あとがき・まとめ
コンテナのイメージをDocker Hubの汎用品にすることでLinuxのユーザーや権限周りで戸惑うこともありましたが概ね3日くらいで検証を終えました。
MariaDBのバージョン違いによるDBのリストアによるトラブルやら、Docker HUBのphp-fpmの拡張機能追加の面倒くささなど予定外の時間を取られました。
ファイルの大文字小文字違いのファイルがあったがWindows上へのボリュームのバインドだったため意図せず動作していることも判明しました。
上記説明ではVSCodeでコマンドを実行していました。
AWSクラウドサービスのEC2でDockerを利用する場合などSSH接続になりますのでそういった設定も行ってあります。
Dockerについて
Docker/コンテナ環境のメリットはいくつかあることは分かったものの・・・
私が関わる仕事では導入する時間的コストを考えるとメリットは少ないという印象です。
特にElasticacheやRDSを採用しているとnginx+php-fpmのアップデート以外にバージョン検証をすることが少ないです。
それに緊急の脆弱性が見つかったとしても本当に対処しなければならないことはあまりないです。
堅牢なシステムを構築しセキュリティーホールとなりえる入口も狭く最小限にしていればなおさらです。
メリットとされているコンテナを分ける使い方として同一サーバーハードウェア上でのプロジェクトの共存というのもありますが・・・
プロジェクトごとに企業が異なっていて機密保持契約もぞれぞれ出る場合が私の場合は多い点から共存はトラブルの元なので避けています。
結局のところプロジェクトの要件次第でメリットが多いこともあると思いますので必要と思う方はDockerの導入を検討してみてはいかがでしょうか。
実際なところネットワーク・ハードウェアの知識、Linux OS・Windows OSの知識に合わせてDocker/Containerの知識も必要です。
理解して使わないとトラブルが発生しやすくトラブルシュートに時間や費用(専門サポートなど)が掛かったりという場面も見てきました。
便利・簡単というざっくりとしたメリット情報ばかりで根本的なシステム知識の壁などのデメリットが記載されていない似たような内容ばかりの記事が多くみられる現状はどうなのでしょうか・・・
(おまけ)ページロードパフォーマンス
Google Chromeにてページ読み込みした際の全体的な読み込みパフォーマンス情報です。(PC向けの一番重たいコンテンツを含むページ)
完成したウェブサイトではないので一般データとは言えませんが、コンテンツがない状態のページで1秒近くなのでちょっと掛かりすぎと言えそうです。
(途中に謎の空白があるのでVuetifyを利用する構成だとこれくらいが一般的なのかもしれませんが・・・)
フォントアイコンなどの検証もしているのでこの辺りのパフォーマンスはタイミングを見て調整していくことになりそうです。