モダンっぽそうな環境の構築にトライしたので忘れないうちにメモ
環境
- PHP8.1
- Laravel 9
- Vite
- TypeScript
- MySQL
Laravelコンテナ、MySQLコンテナをdocker-compose.ymlで立てる
Docker環境はDocker Desktop
目標
- Laravelトップページの表示
- TypeScriptの実行
- Laravel - MySQL間の連携
1. dockerfile, docker-compose.ymlを作成
laravelはcomposerで導入
laravel sailというのがあるみたいなので別の機会に試すことにする
FROM centos:centos7
WORKDIR /var/www/html
RUN yum -y update && \
yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm
# php
RUN yum -y install php --enablerepo=remi-php81 \
php-mbstring \
php-pdo \
php-dom \
php-mysqlhd \
zip \
unzip
# composer
RUN curl -sS https://getcomposer.org/installer | php -- --version=2.4.4 && \
mv composer.phar /usr/local/bin/composer
# node
RUN curl -sL https://rpm.nodesource.com/setup_16.x | bash - && \
yum -y install nodejs
version: '3'
services:
web:
container_name: web
build: .
tty: true # up後も起動し続けるようにする
privileged: true # systemctlを有効化する
command: "/sbin/init" # systemctlを有効化する
ports:
- "80:80"
- "5173:5173" # Viteのdevサーバ用ポート
volumes:
- ./web:/var/www/html
db:
container_name: db
image: mysql:8.0.15
tty: true # up後も起動し続けるようにする
environment:
MYSQL_DATABASE: hoge
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: admin
ports:
- 3306:3306
volumes:
- ./db/data:/var/lib/mysql # データの永続化マウント
- ./db/conf.d:/etc/mysql/conf.d # 設定の永続化マウント
2. コンテナ作成
dockerfile, docker-compose.ymlを適当なディレクトリに置く
今回はDocuments直下にディレクトリを切って配置
こんな感じ↓
Documents
└ laravel9
├ dockerfile
└ dockercompose.yml
powerShellでコンテナ起動
cd $HOME/Documents/laravel9
docker-compose up -d
-dオプションをつけていればバックグラウンドで起動してくれるので、コンテナ立てながら好きなことができる
--buildオプションをつけていれば、upのたびにイメージのビルドからやってくれるらしい
一応確認
それっぽいのが2つ立ち上がってればOKとする
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b2ab41fb888 laravel9-web "/sbin/init" 15 seconds ago Up 13 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:5173->5173/tcp web
2c984059cd45 mysql:8.0.15 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:3306->3306/tcp, 33060/tcp db
ディレクトリ構成↓
Documents
└ laravel9
├ db # MySQLのマウント
├ web # Laravelのマウント
├ dockerfile
└ dockercompose.yml
3. Laravel 9
コンテナにインしてインストール実施
docker exec -it web bash
composer create-project laravel/laravel=9.* /var/www/html
Info from https://repo.packagist.org: #StandWithUkraine
...
> @php artisan key:generate --ansi
INFO Application key set successfully.
envのappkey作成まで自動でやってくれる
早速ビルトインサーバを立てて画面で確認
php artisan serve --host 0.0.0.0 --port=80
Server running on [http://0.0.0.0:80].
Dockerコンテナ外から内部サーバを参照できるようにするために--host 0.0.0.0
をつける
--port=80
でポートを指定、今回のwebコンテナは80番ポートを開けてあるので80番で設定(5173ポートも開けてるのでそっちの指定もできなくはない)
localhost:80に接続して、トップページが出ればok
4. Vite + TypeScript
Viteってそもそも何?って思ったらlaravel-mixみたいなものらしい
vue.jsと作者が同じだとか
4.1 Vite導入から確認まで
package.jsonにViteの記載があるか念のため確認
(Laravel8以降?には標準搭載みたい)
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.7.0",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"vite": "^3.0.0"
}
}
インストール
npm install
npm runしてみる
npm run dev
VITE v3.2.5 ready in 2202 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
LARAVEL v9.43.0 plugin v0.7.1
➜ APP_URL: http://localhost
起動した
webpackと全然違うし、しかも早い!
ただ、この状態だとターミナルの操作ができない(=php artisan serveできない)ので、httpdでサーバを立ち上げる
(ターミナルを複数立ち上げとけばいける?でも複数立ち上げたくない)
vi /etc/httpd/conf/httpd.conf
# ドキュメントルートだけ変更
DocumentRoot: /var/www/html/public
systemctl start httpd
ここで画面エラー
The stream or file "/var/www/html/storage/logs/laravel.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
よく見るやつ
以下コマンドを実行
chmod -R 777 storage bootstrap/cache
パーミッション周りは何も気にせず777にしがちなので、勉強の余地あり
画面を表示
npm run dev
しながらでもLaravelトップページが見れるのを確認する
4.2 TypeScriptをコンパイルしてみる
公式を参照しつつViteのコンパイルを動かしてみる
https://readouble.com/laravel/9.x/ja/vite.html
resources/jsに以下のファイルを作成
console.log("ts");
resources/views/welcome.blade.phpに@viteディレクティブを追加
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
@vite('resources/js/app.ts')
vite.config.jsのビルド対象を修正
export default defineConfig({
plugins: [
laravel({
input: ['resources/js/app.ts'],
refresh: true,
}),
],
});
npm run dev
して画面を表示
ここでコンソールエラー
Failed to load resource: net::ERR_EMPTY_RESPONSE
jsが読めてない
出力されているhtmlを確認
<title>Laravel</title>
<script type="module" src="http://127.0.0.1:5173/@vite/client"></script>
<script type="module" src="http://127.0.0.1:5173/resources/js/app.ts"></script>
さっきの@viteディレクティブはこんな感じで展開される
npm run dev
によって、viteのdevサーバが立ち上げられ、そこからファイルを読み取っているイメージ
→http://127.0.0.1:5173
になっているので、これをhttp://localhost:5173
にする
vite.config.jsを修正
server設定を追加
export default defineConfig({
server: {
host: true,
hmr: {
host: "localhost"
},
watch: {
usePolling: true
}
},
plugins: [
laravel({
input: ['resources/js/app.ts'],
refresh: true,
}),
],
});
設定については公式に説明があります
watch: { usePolling: true }
はwindows + WSL2環境下で監視を動作させるための設定
公式にもあるので引用
Linux 用 Windows サブシステム (WSL) 2 での Vite の使用
WSL2 で Vite を実行している場合、ファイルが Windows アプリケーション (非 WSL2 プロセス) によって編集されている場合、ファイル システム監視は機能しません。これは、WSL2 の制限によるものです。これは、WSL2 バックエンドを使用して Docker で実行する場合にも当てはまります。
これを設定しておくと、
tsかwelcome.blade.phpに変更が入った時、自動で画面リロードが走るようになる
npm run dev
して画面を表示し、console.logが出てればok
tsファイルを変更して自動反映されるかどうかも確認しておく
5. MySQL
いつものようにDB接続先を設定
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=hoge
DB_USERNAME=root
DB_PASSWORD=admin
migrate実行でエラー発生
php artisan migrate
SQLSTATE[HY000] [2002] Connection refused
色々調べたところ「DB_HOST」の値はdocker-compose.ymlで設定しているDBのservice名にしないといけないらしいので、下記に変更
DB_CONNECTION=mysql
- DB_HOST=127.0.0.1
+ DB_HOST=db
DB_PORT=3306
DB_DATABASE=hoge
DB_USERNAME=root
DB_PASSWORD=admin
migrate実行で通るのを確認
所感
Viteすごい
docker-compose.ymlも触ったことなかったけどこれもすごい