DockerでLaravelの開発環境を作ってみる(2回目練習Ver)

目次

わけわからない素人がDockerでLaravelの開発環境を作る2回目です。

1回目はここ。

OSは"Ubuntu 20.04.2 LTS"で行います。

Nginxを使う

PHPのDockerイメージ単体でLaravelのページを表示するまで進みました。 次はnginxから表示できるようにしていきます。

使用するnginxのDockerイメージは「nginx:1.21.0-alpine」にしました。 alpineは軽量なLinuxイメージです。

nginxの使い方は分かりませんがdocker hubのページを見て、とりあえず動かしてみました。

https://hub.docker.com/_/nginx

$ docker run --name some-nginx -d -p 8080:80 nginx:1.21.0-alpine

docker psコマンドで動作中なことを確認したら、ブラウザでhttp://127.0.0.1:8080/を参照します。

$ docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                                   NAMES
fcbc778fd223   nginx:1.21.0-alpine   "/docker-entrypoint.…"   14 minutes ago   Up 14 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   some-nginx
nginxが実行中

nginxが実行中

単体では動作することが確認できましたが、これは使わないので停止して削除します。

$ docker stop some-nginx
$ docker rm some-nginx

PHPアプリのコンテナを作る

PHPアプリを動作させるコンテナを作ります。nginxとの動作確認をするため以下のようにディレクトリとファイルを作成します。

www
├─ nginx
│   │ default.conf  ← nginxの設定ファイル
│   └
└─ example-app
     └─ public
          │ index.html  ← HTML動作確認用ファイル
          │ phpinfo.php  ← PHP動作確認用ファイル
          └─

“index.html”

<!DOCTYPE html>
<html>
  <body>
    <h1>PHP Docker container</h1>
  </body>
</html>

“phpinfo.php”

<?php
  phpinfo();

nginxの設定ファイルが必要なのですが、これはLaravel公式の「Deployment」を参考にしました。

nginxの設定ファイルを作成するのにPHPコンテナの情報が必要なため先にPHPコンテナを作成し、開始します。

$ cd www
~/www$ docker run -dit --name php-2nd -v "$PWD":/var/www php:8.0.7-fpm-buster

nginxをPHPコンテナと連携する

nginxの設定にPHPコンテナのIPアドレスが必要なので、PHPコンテナが開始したら、内部に入ります。hostname -iコマンドでIPアドレスを確認します。

$ docker exec -it php-2nd /bin/bash
root@01187583fd24:/var/www/html# hostname -i
172.17.0.2

PHPコンテナのIPアドレスが"172.17.0.2"と表示されました。

これをnginx設定ファイルのFastCGI サーバーfastcgi_passに指定します。例ではPHPとnginx間の通信にUnixドメインソケットを使用していましたが、ここではIPソケットを使用するようにします。

rootにはPHPコンテナに割り当てたディレクトリを指定します。PHPコンテナを作るDockerコマンドのオプションに-v "$PWD":/var/wwwと指定したので、作成した"index.html"と"phpinfo.php"のあるディレクトリwww/example-app/publicは、PHPコンテナでは/var/www/example-app/publicに割り当てられます。

“default.conf"の内容です。

server {
    listen 80;
    server_name example.com;
    root /var/www/example-app/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        # FastCGI サーバー
        fastcgi_pass 172.17.0.2:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

nginxコンテナを開始します。

~www$ docker run --name nginx-2nd -v "$PWD"/nginx:/etc/nginx/conf.d -v "$PWD":/var/www -d -p 8080:80 nginx:1.21.0-alpine

webブラウザでhttp://127.0.0.1:8080/index.htmlを表示してみます。

ブラウザでindex.htmlを表示する

ブラウザでindex.htmlを表示する

次にhttp://127.0.0.1:8080/phpinfo.phpを表示してみます。

ブラウザでphpinfo.phpを表示する

ブラウザでphpinfo.phpを表示する

PHPコンテナのログは以下の内容で、"/phpinfo.php"がGETされたことがわかります。

~/www$ docker logs php-2nd
[09-Jun-2021 03:31:30] NOTICE: fpm is running, pid 1
[09-Jun-2021 03:31:30] NOTICE: ready to handle connections
172.17.0.3 -  09/Jun/2021:03:39:15 +0000 "GET /phpinfo.php" 200

PHPコンテナにLaravelアプリを作成する

nginxからPHPコンテナが参照できるようになったので、Laravelアプリを設定します。 “example-app"ディレクトリは必要ないので削除します。

PHPコンテナ内でComposerをインストールし、Composerを使ってLaravelをインストールします。

root@01187583fd24:/var/www/html# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
root@01187583fd24:/var/www/html# php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
root@01187583fd24:/var/www/html# php composer-setup.php
root@01187583fd24:/var/www/html# php -r "unlink('composer-setup.php');"
root@01187583fd24:/var/www/html# mv composer.phar /usr/local/bin/composer
root@01187583fd24:/var/www/html# apt-get update
root@01187583fd24:/var/www/html# apt-get -y install unzip git
root@01187583fd24:/var/www/html# composer global require laravel/installer
root@01187583fd24:/var/www/html# export PATH="$HOME/.composer/vendor/bin:$PATH"

/var/wwwディレクトリに移動し、laravel newコマンドでLaravelプロジェクトを作ります。

root@01187583fd24:/var/www/html# cd /var/www
root@01187583fd24:/var/www# laravel new example-app

確認のためブラウザでhttp://127.0.0.1:8080を開くとエラーメッセージが表示されました。

UnexpectedValueException
The stream or file "/var/www/example-app/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission denied
http://127.0.0.1:8080/ 
ブラウザにエラー表示されました

ブラウザにエラー表示されました

“/var/www/example-app/storage/logs/laravel.log"ファイルに書き込み権限がないようです。

root@01187583fd24:/var/www/example-app/storage# ls -l
total 12
drwxr-xr-x 3 root root 4096 Jun  1 15:49 app
drwxr-xr-x 6 root root 4096 Jun  1 15:49 framework
drwxr-xr-x 2 root root 4096 Jun  1 15:49 logs

“logs"ディレクトリは"root"ユーザーの所有になっていて、他には書き込み権限がありません。 PHPの権限はよくわからないので今回は他ユーザーに書き込み権限を加えてみました。

root@01187583fd24:/var/www/example-app/storage# chmod o+w logs

今度は”/var/www/example-app/storage/framework/sessions"ディレクトリです。

ErrorException
file_put_contents(/var/www/example-app/storage/framework/sessions/jcMwG82SWJLthSYDG04rQvjwAHS0188rD7XVNOPR): Failed to open stream: Permission denied 

“/var/www/example-app/storage/framework/sessions"ディレクトリに書き込み権限を付けます。

root@01187583fd24:/var/www/example-app/storage# chmod o+w framework/sessions

次は”/var/www/example-app/storage/framework/views"ディレクトリです。

ErrorException
file_put_contents(/var/www/example-app/storage/framework/views/cd3bc8f44536f9c18ad7f5f8d1e21506839ec5af.php): Failed to open stream: Permission denied 

“/var/www/example-app/storage/framework/views"ディレクトリに書き込み権限を付けます。

root@01187583fd24:/var/www/example-app/storage# chmod o+w framework/views

でやっとhttp://127.0.0.1:8080/が見られるようになりました。

ブラウザにLaravelのページが表示されました

ブラウザにLaravelのページが表示されました

2回目でDockerにnginxとPHPの環境を作ることができました。

3回目へ続く。