前提・やること
-
既に作成されているLaravelプロジェクトを、docker環境をWindowsに作ってソース移行し、動くように(デプロイ)する。
コンテナはphp、nginx、mysql、phpmyadmin。 -
Docker Desktop for windows 、WSLはインストール済。
-
下記の参考サイトを手順に環境を作成し、追加で独自カスタマイズ、および出たエラー対応をしていく。
DockerでLaravel開発環境を手軽に構築する手順 - カゴヤのサーバー研究室 -
※最初、以下の記事を参考に作成しようとしたら、nginxが起動してもすぐに停止する、ブラウで502 Bad Gateway のエラーがどうしても解決できなかったので、別の記事を参考にした。
https://reffect.co.jp/laravel/finally-understand-laravel-on-docker#Laravel-3
環境
windows11 home
WSL2
Docker Desktop for windows v4.18.0
Laravel 10
PHP8.2
環境構築
参考サイトを元に進める
https://www.kagoya.jp/howto/cloud/container/docker_laravel/
を参考に進めていく。
- PowerShellで任意の場所に作業フォルダ laravel_docker を作成し、そのフォルダに移動。
mkdir laravel_docker
cd laravel_docker
- laravel_dockerディレクトリ配下に以下のようにディレクトリ・ファイルを作成していく。(参考サイトの図参照)
laravel_docker配下
├docker├ nginx
│ │ └default.conf
│ └ PHP
│ └Dockerfile
│ └PHP.ini
└compose.yml
- compose.yml
laravel_dockerディレクトリ配下に保存。
services:
app:
container_name: app
build: ./docker/php
volumes:
- .:/var/www
nginx:
image: nginx
container_name: nginx
ports:
- 9000:80
volumes:
- .:/var/www
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
working_dir: /var/www
depends_on:
- app
db:
image: mysql:5.7
container_name: db
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: database
MYSQL_USER: db-user
MYSQL_PASSWORD: db-pass
TZ: 'Asia/Tokyo'
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./docker/db/data:/var/lib/mysql
- ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
- ./docker/db/sql:/docker-entrypoint-initdb.d
ports:
- 3306:3306
- php.ini
docker\php 内に保存
ここで、「mbstring.internal_encoding = "UTF-8"」
は最初に;を付けてコメントにする。のちにエラーになったため
参考:https://desuto.net/use-of-mbstring-internal_encoding/
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
;mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
[opcache]
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
- Dockerfile
docker\php 内に保存
FROM php:8.2-fpm
COPY php.ini /usr/local/etc/php/
RUN apt-get update \
&& apt-get install -y zlib1g-dev mariadb-client vim libzip-dev \
&& docker-php-ext-install zip pdo_mysql
#Composer install
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin
WORKDIR /var/www
RUN composer global require "laravel/installer"
- Webサーバー「nginx」の設定ファイル「default.conf」を作成。
ここで、
try_files $uri $uri/ /index.php$query_string;
の行は、のちにLaravelでgetパラメータが渡らないバグの原因となったので、
try_files $uri $uri/ /index.php?$query_string;
と修正。
server {
listen 80;
root /var/www/laravel-project/public;
index index.php;
location / {
root /var/www/laravel-project/public;
index index.php;
# try_files $uri $uri/ /index.php$query_string;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
- compose.ymlを使い、Dockerコンテナを起動。
docker compose up -d
Dockerコンテナが正常に起動していることを確認。
docker compose ps
正常に起動していれば、コンテナ一覧がSTATUS UPで表示される。
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
app docker_kagoya_ubuntu-app "docker-php-entrypoi…" app 4 hours ago Up 4 hours 9000/tcp
db mysql:5.7 "docker-entrypoint.s…" db 4 hours ago Up 4 hours 0.0.0.0:3306->3306/tcp, 33060/tcp
nginx nginx "/docker-entrypoint.…" nginx 4 hours ago Up 4 hours 0.0.0.0:9000->80/tcp
- 作成したDockerコンテナの中へ入り、Laravelアプリを作成。
docker compose exec app bash
- Dockerコンテナの中に入って、以下コマンドを実行。
composer create-project --prefer-dist laravel/laravel laravel-project "10.*"
lsコマンドを実行で、以下のようにLaravelアプリが作成されたことを確認できる。
- storageディレクトリの所有者をwww-dataに変更。
cd laravel-project
chown www-data storage/ -R
-
Laravelが起動したことを確認するため、ブラウザで以下URLへアクセス。
http://DockerがインストールされたサーバーのIPアドレス:9000
(今回の場合、http://localhost:9000/)
成功していれば、以下のようにLaravelのウェルカムページが表示される。
-
ここまでが、参考サイトによる構築。
ここからさらに変更を加えていく。
phpmyadminを追加
次に、phpmyadminを追加してみる。
compose.ymlの下部に下記を追加して、コンテナを作り直す。
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=mysql
# - PMA_USER=user
# - PMA_PASSWORD=password
links:
- db
ports:
- 8081:80
volumes:
- /sessions
volumes:
mysql-data:
すると、http://localhost:8081/
でphpMyadminが起動、
サーバ:db
ユーザ名:root
パスワード:root
で入ることができた。
DBのmigrate
- laravelからの接続
Laravelルートにある.envファイルを開き、データベース接続を設定。
DB名、ユーザ名、パスワードなどを先ほどdocker-compose.ymlに設定した値に合わせる。
DB_CONNECTION_=mysql
#DB_HOST:container_name を入れる↓
DB_HOST=db
DB_PORT=3306
DB_DATABASE=(任意)
DB_USERNAME=root
DB_PASSWORD=root
設定後、
php artisan config:cache
でキャッシュクリア。
次にappコンテナの中に入って、
docker compose exec app bash
php artisan migrate
をしてエラーが出ず、テーブルが作成されればLaravelとmysqlコンテナが接続完了。
# php artisan migrate
INFO Preparing database.
Creating migration table ......................................................................... 56ms DONE
INFO Running migrations.
2014_10_12_000000_create_users_table ............................................................. 66ms DONE
2014_10_12_100000_create_password_reset_tokens_table ............................................. 47ms DONE
2014_10_12_100000_create_password_resets_table ................................................... 36ms DONE
2019_08_19_000000_create_failed_jobs_table ....................................................... 48ms DONE
2019_12_14_000001_create_personal_access_tokens_table ............................................ 56ms DONE
2023_02_19_045335_create_people_table ............................................................ 16ms DONE
2023_02_19_085749_create_boards_table ............................................................ 18ms DONE
2023_02_20_055257_create_restdata_table .......................................................... 18ms DONE
2023_02_20_234754_create_sessions_table .......................................................... 94ms DONE
2023_03_11_144738_add_column_to_users_table ...................................................... 34ms DONE
laravelのログイン機能を付ける
appコンテナの中に入る。
docker compose exec app bash
https://readouble.com/laravel/10.x/ja/starter-kits.html
を参考にLaravel Breezeをインストール。
composer require laravel/breeze --dev
php artisan breeze:install
php artisan migrate
npm install
npm run dev
npm run build
途中でnpmがないと言われるので、
https://www.softel.co.jp/blogs/tech/archives/6487
こちらを参考にインストール(rootでない人は、随時先頭にsudoを付けて実行)。それから続きを再開。
apt install nodejs npm
npm install -g n
n stable
apt purge nodejs npm
exec $SHELL -l
バージョンを確認
node -v
v18.16.0
npm -v
9.5.1
- 環境設定は基本的にこれでOK。
次に、既存の環境からソースを移行して、デプロイしてみる。
ソースを移行し、動作させたところ、ログイン画面が正常に表示されない。
Vite manifest not found at: /var/www/laravel-project/public/build/manifest.json
エラー。
https://biz.addisteria.com/laravel_vite_errors/
このページを参考に、
npm run build
を実行したら、正常なページが出るようになった。
-
次に、Laravelトップ画面に下記のエラーが出るようになり、
file_put_contents : failed to open stream: No such file or directory
https://prograshi.com/framework/laravel/error-file_put_contents/
このページの対処法で解決した。
$ php artisan config:cache
$ php artisan config:clear
$ composer dump-autoload -o
-
storageフォルダへのシンボリックリンクを張る
storageフォルダ内にある、画像アップロードした画像が表示されないので、シンボリックリンクを張る。
storage/app/publicディレクトリは、プロファイルアバターなど、一般にアクセス可能である必要のあるユーザー生成ファイルを保存するために使用します。このディレクトリを指すシンボリックリンクをpublic/storageに作成する必要があります。php artisan storage:link Artisanコマンドを使用してリンクを作成できます。
https://readouble.com/laravel/10.x/ja/structure.html
appコンテナの中に入って
docker compose exec app bash
# php artisan storage:link
INFO The [public/storage] link has been connected to [storage/app/public].
することで、リンクが作られた。
そのほか、独自に使用しているシンボリックリンクがあれば、それも作成する。
例)
ln -s /var/www/laravel-project/storage/app/public/upload upload
(\laravel-project\storage フォルダで実行)
動作の重さ改善(ubuntu内にファイル移転)
ここまでで、既に動いているLaravelのソースを移行し、おおよその動作確認はできた。が、ものすごく動作が重い。簡単な画面遷移で5~10秒ぐらいかかる感じ。
これは下記による問題のようなので、これを改善してみる。
WindowsでDockerを使う時、正しくファイル配置しないと激重になるので注意
https://qiita.com/minato-naka/items/84508472c04f628e576e
Windows内にubuntuをインストールし、アプリコードをその中に置くと早くなるとのこと。
そこで上記の記事を参考にやってみる。
-
Ubuntu-22.04をインストールして再起動。
エクスプローラーでのパスが
\wsl$\Ubuntu-22.04
となるので、作業フォルダを今回、docker_kagoya_ubuntu として、
・docker作業フォルダ
\wsl.localhost\Ubuntu-22.04\home\<ユーザー名>\docker_kagoya_ubuntu
・Laravelフォルダ
\wsl.localhost\Ubuntu-22.04\home\<ユーザー名>\docker_kagoya_ubuntu\laravel-project
として、dockerを起動。
起動はできるが、
http://localhost:9000/
でエラー出る。
The stream or file "/var/www/laravel-project/storage/logs/laravel-2023-04-29.log" could not be opened in append mode: Failed to open stream: Permission denied The exception occurred while attempting to log: The stream or file
-
パーミッションが何とかと言っているので、パーミッション設定をしてみる。
docker compose exec app bash
で中に入り、
https://qiita.com/ky-jp16/items/9956ea9dd391f0d69127
を参考にパーミッションを設定。
エラーは解消。
ubuntu内のファイルを編集できるように対応
- その後、アプリのソースを一部変更しようとしたところ、権限がなくファイルを変更できない、とエラー。
WSL 2 の Linux ファイルシステムを bind mount してコンテナー内開発を行う場合、権限を適切に設定しないと、コンテナー内で作成したファイルが、ホストの WSL 2 や Windows 側で操作できなくなってしまうなどの問題が発生します。
https://futureys.tokyo/how-permission-should-be-set-for-developing-inside-a-container-using-wsl-2/
WSL で デフォルトユーザ を変更する方法
https://devlights.hatenablog.com/entry/2021/05/29/070000
上記の記事を参考に対応。
管理者権限でPowerShellを起動し、
ubuntu2204 config --default-user root
でファイルが編集できるようになった。
- ここまでの状態で、とりあえず完了。
アプリのソースファイルをubuntu内に移動したことによって、移行したLaravelアプリの動作が劇的に軽くなり、問題なく動くようになった。
※後に気づいた点があったら追記します。