DockerでLaravel、Vue環境を作成

## はじめに
以前、Laravel10でvue3を動作させる環境を構築してみた。

https://qiita.com/kenji123/items/15c7fe0910c706d495cc

今回はdockerを使用して書き換えてみた。
Chatgpt大先生に質問しながら作成したが、整理しないとわからない状況だったので、整理し結果動いたのを記録に残すことにした。

## 前提
Docker環境を事前にセットアップしていること

## フォルダ構成
今回はlaravel-appフォルダにlaravelプロジェクトを作った。
```
.
├── Dockerfile
├── docker-compose.yml
├── laravel-app
│   ├── README.md
│   ├── app
│   ├── artisan
│   ├── bootstrap
│   ├── composer.json
│   ├── composer.lock
│   ├── config
│   ├── database
│   ├── package.json
│   ├── phpunit.xml
│   ├── public
│   ├── resources
│   ├── routes
│   ├── storage
│   ├── tests
│   ├── vendor
│   └── vite.config.js
└── nginx.conf
```

## 手順
### 任意ディレクトリ作成
```
mkdir my-laravel-project
```

### 3ファイル作成
#### Dockerfile

```Dockerfile
FROM php:8.1-fpm

# 必要なパッケージのインストールとDocker PHP Extensionsのインストール
RUN apt-get update && apt-get upgrade -y && \
  apt-get install -y libpng-dev libjpeg-dev libfreetype6-dev zip git unzip && \
  docker-php-ext-configure gd --with-freetype --with-jpeg && \
  docker-php-ext-install gd pdo pdo_mysql && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/*

# Composerのインストール
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Node.jsのインストール
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - && \
  apt-get install -y nodejs npm
```

#### docker-compose-yml

```docker-compose-yml
version: '3'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: laravel_app
    volumes:
      - ./laravel-app/:/var/www/laravel-app
    ports:
      - "8000:8000"
      - "9000:9000"
      - "5173:5173"
    working_dir: /var/www/laravel-app
    environment:
      - "DB_HOST=mysql"
      - "DB_PORT=3306"
      - "DB_DATABASE=laravel"
      - "DB_USERNAME=root"
      - "DB_PASSWORD=secret"
  nginx:
    image: nginx:alpine
    container_name: nginx_server
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./:/var/www
  mysql:
    image: mysql:5.7
    container_name: mysql_db
    environment:
      - "MYSQL_DATABASE=laravel"
      # - "MYSQL_USER=root"
      - "MYSQL_PASSWORD=secret"
      - "MYSQL_ROOT_PASSWORD=secret"
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:
```

 #### nginx.conf

```nginx
server {
    listen 80;
    index index.php index.html;
    root /var/www/laravel-app/public;
    location / {
        proxy_pass http://app:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    location ~ \.php$ {
        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;
    }
}

```

### ディレクトリにプロジェクト作成
laravel-appフォルダが作成され、そこにlaravelプロジェクトが作成される。
```
docker-compose run --rm app composer create-project --prefer-dist laravel/laravel .
```
どこにも　laravel-appの名前はないが、以下のようにしてlaravel-appフォルダを作成している。
docker-compose.ymlのappサービス定義を見ると、working_dirは/var/www/laravel-appと設定している。
このworking_dirは、ホストの./laravel-app/ディレクトリにバインドしている。
したがって、コンテナ内でcomposer create-projectコマンドを実行すると、ホストの./laravel-app/ディレクトリにLaravelプロジェクトが作成されることになる。


### コンテナ起動
```
docker-compose up -d
```

### コンテナに入り作業

```
docker-compose exec app npm install
```

vuetifyインストール
```
docker-compose exec app npm install @vitejs/plugin-vue vite-plugin-vuetify --save-dev
```

### vite.config.js修正
```vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from "@vitejs/plugin-vue";
import vuetify from 'vite-plugin-vuetify';

export default defineConfig({
    plugins: [
        vue(),
        vuetify(),
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
    ],
    server: {
        port: 5173,
        host: '0.0.0.0'
    }
});
```


### app.js修正
```resources/js/app.js
import './bootstrap';
import '../css/app.css';
import { createApp } from 'vue'
import App from '../views/App.vue'
createApp(App).mount("#app")
```

### welcome.blade.php修正
初期インストール時のwelcome.blade.phpを修正
resources/views/welcome.blade.php
```welcome.blade.html
<!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 Vite Vue</title>
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>

<body>
    <div id="app"></div>
</body>

</html>

```

### App.vue作成
resources/views/App.vue
```App.vue
<template>
    <div class="page">
        <p>{{ counter }}</p>
        <button @click="counter += 1">
            click!
        </button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            counter: 0,
        }
    },
}
</script>
```


Laravel実行
```
docker-compose exec app php artisan serve --host=0.0.0.0 --port=8000
```

Vite実行
```
docker-compose exec app npm run dev
```


### 画面
簡素ですが以下の画面が表示されます。
クリックすると数が増えます。
![スクリーンショット 2023-09-16 19.42.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/ce372296-7393-89d4-cdfb-b6a6992df4c2.png)

### 終わりに
前回はMAMPで環境を作ったが、dockerを使用するとポートの衝突が発生した。
今回の設定で無理やりかもしれないが対応できたが、さらに内容の理解が必要な状況で、DBの設定も.envの設定だけだが特に使用していないので省いた。
手順通りすれば動くところまではできたので、表面的ではあるが記載することにした。