LAMP+CakePHP3開発環境をVSCodeRemote+Dockerで構築① -Docker編-からの続きです。
VSCodeでPHPの開発をするにあたり、XDebugやPHP Intellisenseなどの拡張を入れようとするとVSCodeのインストールされている自PCにもPHPをインストールする必要がありますが、VSCode Remote Developmentを利用するとDockerのコンテナ内で全て完結できました。
導入の際に問題が起きてかなりはまってしまったので、その際の対応を記載しています。
完成した環境はGitHubにアップロードしてあります。
VSCode Remote Developmentの導入
Docker関連のファイルは前回作成したものをそのまま使用しています。
以下の記事を参考にして導入してみます。
Visual Studio CodeのRemote DevelopmentとDockerで快適な開発環境をゲット
すると、コンテナの起動とVSCodeからコンテナへの接続は上手くいきます。
が、ブラウザからhttp://localhost:8093/ へアクセスすると「ERR_EMPTY_RESPONSE」と表示され接続できません。
VSCodeRemoteをコンテナに接続するとコンテナ内のサーバーへアクセスできなくなる問題
調査
curl http://localhost:8093
エラー
curl: (52) Empty reply from server
コンテナ内で以下のコマンドを実行すると
curl http://localhost:80
エラー
curl: (7) Failed to connect to ::1: Cannot assign requested address
となりこちらもエラーが出ます。
localhostを127.0.0.1に置き換えても同様です。
以下の記事達を参考にし、どうもコンテナは起動しているがサーバーが起動していない状態にありそうだという事がわかりますが、解決しません。
Dockerコンテナで起動したサーバにアクセスできないときの確認と対処方法
docker上のアプリにlocalhostでアクセスしたらERR_EMPTY_RESPONSEが出る
VSCodeRemoteで接続した際にのみアクセスできなくなるので、そちらに原因がありそうだと当たりをつけて公式ドキュメントを読んでみます。
Visual Studio Code | Developing inside a Container
公式ドキュメントを読んでみて大事そうなところ
・VSCodeRemoteでコンテナに接続した場合、コンテナを開いたrootディレクトリに対してworkspaceという名前のvolumeが作られる。
・rootディレクトリは設定で変更可能
・rootディレクトリ直下にdevcontainerフォルダが作られる。
フォルダ構成は以下の様な形
devcontainer
- devcontainer.json
- docker-compose.yml(VSCodeによって生成された、設定上書き用ファイル)
...
他のファイルやフォルダ達
docker-compose.yml(コンテナ生成の元になっている自分で用意したファイル)
・ このうちdevcontainer.jsonには以下の設定項目があり、上から指定されている順にdocker-compose.ymlが読み込まれ、上書きされていく。
"dockerComposeFile": [
"../docker-compose.yml",
"docker-compose.yml"
],
以上を踏まえて問題となっていた箇所
自動生成されたdocker-compose.ymlには、以下の設定がされています。
これは、コンテナがすぐに終了してしまわないようにするため設定されている様です。
# Overrides default command so things don't shut down after the process ends.
command: /bin/sh -c "while sleep 1000; do :; done"
また、用意してあるDockerFileでは、サーバーを自動起動するために以下のコマンドを実行しています。
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
Docker側の仕様として、docker-compose.ymlにcommandが記載してあるとDockerFileで記載したCMDを上書きするらしく、このCMDが実行されていないためサーバーが立ち上がらずに問題が起きていたようです。
以下の様に修正したところ、問題なくコンテナのサーバーにアクセスできました。
# Overrides default command so things don't shut down after the process ends.
command: /bin/sh -c "/usr/sbin/httpd -DFOREGROUND; while sleep 1000; do :; done"