LaravelとNuxt.jsをVSCodeで開発する環境をDockerで用意した【Laravel編】

初めてDockerの開発環境を一から用意したので、その時の奮闘を内心も含めて記録しました。環境は以下になります。

  • Windows 10 20H2
  • Docker Desktop for Windows v20.10.8
  • npm v6.14.16(あまり関係ないけど)
  • composer v2.1.6(こちらもあまり関係ない)
  • Visutal Studio Code v1.60.2(Remote containersの拡張機能を使う)

覚えが悪くコマンドの書き方を忘れてしまうので、以下の説明では同じコマンドを何度も記載しています。ご了承ください。

経緯

思い立ったきっかけ

LaravelとNuxt.jsをなんとなく使えるようになったし、自分でなにかWebアプリケーション作りたいな。よし、作ろう!

どこで作ろうか?

LaravelとNuxt.jsを多少使えるからそれが簡単に使えそうなところがいいな。ConoHaのVPSだとLaravelがテンプレートから作れる。よし、これにしよう!

どうやって開発しよう?

Dockerとかいう便利そうなのがある。VSCodeの拡張機能にあるRemote containers というのも便利そう。よし、これ使おう!

Laravel環境構築

各種アプリのインストール

Docker、Composer、Node.jsをインストールします。Node.jsはLaravel関係ないけど一緒にインストール。

Dockerfileの作成

とりあえずC:¥projectというフォルダを作りDockerfileを作成する。

Dockerイメージの選択

ConoHaのLaravelテンプレートは「centos-7.9」ってなってるからこれにしよう。でも大抵のLaravel環境構築サンプルはCentOSから作ってる事が無いのでOSはあんまり気にすることないのかな?まあいいや。ということで以下のようにDockerfileを編集。

イメージ作成

ビルドは「docker build .」だけで出来るけど一応名前も付けておこう。コマンドプロンプトを起動してC:¥projectに移動してイメージの名前はtestimg1でいっか。

実行コマンド

c:\>cd c:\project

c:\project> docker build -t testimg1 .

コンテナ作成

作成したイメージからコンテナを作成して接続できるか試してみよう。名前はtestcon1にしておこう。よし何となく使えてる。

実行コマンド

c:\project> docker run -itd --name testcon1 testimg1

c:\project> docker exec -it testcon1 bash

Webサーバーの用意

どうせphp artisan serveでPHPのビルトインサーバーでテストするわけだから要らない気がするけど、せっかくなのでApacheも用意しておこうかな。Apacheは動いているんだろうか?

実行コマンド

# systemctl status httpd

なんか知らんけど「Failed to get D-Bus connection: Operation not permitted」とかいうエラーで確認できない。。。

調べてみるとDocker runする時に以下のオプション両方が必要らしい。

  • --privileged
  • /sbin/init
参考 CentOS7のDockerコンテナでsystemctlを使えるようにする - QiitaQiita

一旦コンテナから抜けて、コンテナ停止&削除して、さっきのオプションを追加して実行して再接続してsystemctlで確認。

実行コマンド

# exit

c:\project>docker stop testcon1

c:\project>docker rm testcon1

c:\project>docker run -itd --privileged --name testcon1 testimg1 /sbin/init

c:\project>docker exec -it testcon1 bash

# systemctl status httpd

「Unit httpd.service could not be found.」とメッセージが表示され、systemctlが動いてくれて、Apacheがインストールされていないことが確認できた。

入ってなかったのでApacheをインストールするために以下のようにDockerfileを編集し再度testimg1をビルドする。インストールコマンドはググって出てきたのを適当にコピペ。とりあえず動けばいいや。

実行コマンド

# exit

c:\project>docker build -t testimg1 .

また何かエラーでた。「Failed to connect to ~~」となっていて通信できてないっぽい。そういえばプロキシ通さないと外出られなさそう。

CentOSでプロキシ使うには環境変数http_proxy、https_proxyを指定してやれば良いらしい。

参考 Docker + CentOS7 で Proxy 越え - しまかぜメモしまかぜメモ

という事でDockerfileを以下のように編集。勿論プロキシのIPやポートは自分の環境に合わせる。

再度ビルドして、既存のコンテナを削除して、コンテナを再作成して、コンテナに再接続して、Apacheのインストール結果を確認してみる。

実行コマンド

c:\project>docker build -t testimg1 .

c:\project>docker rm testcon1

c:\project>docker run -itd --privileged --name testcon1 testimg1 /sbin/init

c:\project>docker exec -it testcon1 bash

# systemctl status httpd

先ほどと違ってactiveって表示されたりしてるので入ったっぽい。

PHPの用意

phpも入っていないようなのでインストールする。

インストールするコマンドをググってDockerfileにコピペ。いるかどうか分からないモジュールがいっぱいあるけどまあいいや。

ビルドしてコンテナを再作成して接続するとphpがインストールされた。

Laravelのプロジェクト作成

そろそろLaravelのプロジェクト作ろうかな。フォルダもちょっと整理しよう。C:¥projectの下にapiというフォルダを作ってLaravelの開発環境はそっちにまとめよう。ソースはDockerとは別にしようと思ったけどVSCodeのRemote containersでDocker上で開発するからこっちでいっか。ホスト上で作成したファイルをコンテナ内にコピーしようとすると同じフォルダに無いとコピーできないし。

実行コマンド

c:\project>mkdir api

c:\project>move Dockerfile api

c:\project>cd api

c:\project>composer create-project laravel/laravel src

ちなみに--prefer-distは要らないはず。

Laravelのプロジェクト作成コマンドの意味

さて、Laravelのプロジェクトも作成できたのでコンテナ内で動かしてみよう。まずはDockerfileでファイルをコンテナ内にコピーするよう編集して。

イメージを再作成&コンテナ再作成してコンテナに接続し、ソースはコピーされてるかな?

されてる。よし、次はブラウザで接続してみよう。一旦コンテナを抜けて削除して、ポートのマッピングはphp artisan serve用の8000番とApacheの80番でいっか。

実行コマンド

# exit

c:\project\api>docker stop testcon1 && docker rm testcon1

c:\project\api>docker run -itd -p 8000:8000 -p 80:80 --privileged --name testcon1 testimg1 /sbin/init

c:\project\api>docker exec -it testcon1 bash

# cd /var/www/html/

# php artisan serve

これでブラウザからアクセス出来ると思うけどどうだろう?

ちくしょう。

調べてみるとデフォルトではphpのビルトインサーバーはリモートからの接続は許可していないらしく実行時に「--host 0.0.0.0」と指定が必要の様です。自分のPC上で動いているんだからリモートじゃないじゃんと思うかもしれないけど多分Docker内のネットワークを経由しているのでリモート扱いとなるのでしょう。コンテナ内で以下の様にコマンドを実行し、再度ブラウザでアクセスすると開発サーバーに接続することが出来ました。

実行コマンド

# php artisan serve --host 0.0.0.0

Apacheでの実行

php artisan serveだけで十分な気がするけどついでにApacheからのアクセスも試してみよう。DocumentRootを/var/www/html/publcにするだけでいいか。設定ファイルの場所を調べてみると/etc/httpd/conf/httpd.confなので変更してApacheを再起動っと。これで出来るかな?

実行コマンド

# vi /etc/httpd/conf/httpd.conf

DocumentRootを/var/www/html/publicに変更

# systemctl restart httpd

やっぱダメかー。

logsディレクトリに権限設定して。

実行コマンド

# chown apache:apache /var/www/html/storage/logs

まだダメ。

sessionsにも権限設定。既存のセッションファイルらしきものがあるので-Rで再帰指定。

実行コマンド

# chown apache:apache -R /var/www/html/storage/framework/sessions

出来た!

せっかくなのでDockerfileに追記しておこう。

後々似たような事が他のディレクトリでもあったので27~28行目も一緒に追記。まだ他にもあるかも。

それからhttpd.confも編集しておかないと。まずはコンテナ内からhttpd.confを取り出して。

実行コマンド

c:\project\api>docker cp testcon1:/etc/httpd/conf/httpd.conf ./httpd.conf

DocumentRootを/var/www/html/publicに変更しておいて、ビルド時にイメージ内にコピーするようDockerfileを編集。

これでコンテナ起動するだけでApacheからLaravelが見られるようになった。

Laravelのテスト

試しに一個ルートを作ってみよう。/var/www/html/routes内のweb.phpを編集してtestというルートを作ってみる。

あれ?見えない?

調べてみるとhttpd.confの151行目にある「AllowOverride None」を「AllowOverride All」にする必要があるとのこと。編集してApacheを再起動すると表示された。.htaccessの設定が使えるようにする必要があると書いてあったけどよくわからない。もうちょっとちゃんと理解して設定するべきかもしれないけどとりあえずいいや。

最後に

あんまり開発環境と関係ない話も入ってきてしまい、長くなったので一旦ここまで。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です