LaravelとVueのプロジェクトを分離してDocker上にローカル環境を構築する

# はじめに

LaravelのコンテナにLaravelプロジェクトをインストールし、laravel uiやviteプラグインを使用してVueをインストールする記事は多く見られたが、LaravelとVueのコンテナにそれぞれのプロジェクトをインストールして環境構築をしている記事が調べた限り全然見つからなかったので、自分用にメモとして書いていこうと思います。

[こちらの記事](https://qiita.com/nagi125/items/09ddbbfa923c0999494e)が大変参考になりました。



# バージョン

- Docker: 20.10.24
- docker-compose: 1.29.2
- PHP: 8.2
- Laravel: 9系
- nginx: 1.23.4
- node.js: 20.11.0
- Vue: 3



# ディレクトリ構成

``` console
.
├── api ← Laravelのプロジェクトを格納するフォルダ
├── docker
│   ├── api
│   │   ├── Dockerfile
│   │   └── php.ini
│   ├── nginx
│   │   └── default.conf
│   └── web
│       └── Dockerfile
├── docker-compose.yml
├── .env
└── web ← Vueのプロジェクトを格納するフォルダ
```



# Docker

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

services:
  nginx:
    image: nginx:1.23.4-alpine
    container_name: ${PEOJECT_NAME}_nginx
    ports:
      - 80:80
    volumes:
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    tty: true
    restart: always
    depends_on:
      - web

  web:
    container_name: ${PEOJECT_NAME}_web
    build: ./docker/web
    environment:
      PORT: '3000'
      HOST: '0.0.0.0'
    expose:
      - 3000
    volumes:
      - ./web:/app
    stdin_open: true
    tty: true
    restart: always
    depends_on:
      - api

  api:
    container_name: ${PEOJECT_NAME}_api
    build: ./docker/api
    volumes:
      - ./api:/app
    expose:
      - 9000
    tty: true
    restart: always
```


``` .env:.env
PROJECT_NAME=laravel-vue ← 値は適当に変えてください
```


``` Dockerfile:docker/web/Dockerfile
FROM node:20.11.0-alpine

RUN apk update && \
    apk add git && \
    apk add --no-cache curl && \
    curl -o- -L https://yarnpkg.com/install.sh | sh && \
    yarn global add @vue/cli

WORKDIR /app

CMD ["/bin/ash"]
```


``` Dockerfile:docker/api/Dockerfile
FROM php:8.2-fpm-alpine

# install library
RUN apk update && \
    apk add --no-cache --virtual .php-builds oniguruma-dev git zip unzip

# add php-ext-module
RUN docker-php-ext-install mbstring && \
    docker-php-ext-enable mbstring

# install composer
COPY --from=composer /usr/bin/composer /usr/bin/composer

WORKDIR /app
```



# nginx

``` nginx:docker/nginx/default.conf
server {
    server_name localhost;
    root        /app/public;
    index       index.php;

    proxy_set_header Host               $host;
    proxy_set_header X-Real-IP          $remote_addr;
    proxy_set_header X-Forwarded-Host   $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;

    location / {
        proxy_pass http://web:3000;
    }

    location /api {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass  api:9000;
        fastcgi_index index.php;

        include       fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
```
> php.iniの設定は題意と関係ないので省略します。



# コンテナ起動から確認まで

``` console
$ docker-compose up -d --build ← 初回は時間がかかります

$ docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                NAMES
db5764b75840   nginx:1.23.4-alpine   "/docker-entrypoint.…"   44 seconds ago   Up 43 seconds   0.0.0.0:80->80/tcp   laravel-vue_nginx
a514b6b13887   laravel-vue_web       "docker-entrypoint.s…"   44 seconds ago   Up 43 seconds   3000/tcp             laravel-vue_web
ca89a4aad7ad   laravel-vue_api       "docker-php-entrypoi…"   45 seconds ago   Up 44 seconds   9000/tcp             laravel-vue_api
```



# Laravelインストール

app直下に入れる

``` terminal
$ docker-compose exec api composer create-project "laravel/laravel=9.*" --prefer-dist .
```


# Vueインストール

app直下に入れる

``` console
$ docker-compose exec web vue create .
?  Your connection to the default yarn registry seems to be slow.
   Use https://registry.npmmirror.com for faster installation? (Y/n)

? Generate project in current directory? (Y/n)

? Please pick a preset: (Use arrow keys)
❯ Default ([Vue 3] babel, eslint)
  Default ([Vue 2] babel, eslint) 
  Manually select features

? Please pick a preset: Default ([Vue 3] babel, eslint)
? Pick the package manager to use when installing dependencies: (Use arrow keys)
❯ Use Yarn
  Use NPM 
```
インストール時の設定については[こちらの記事](https://qiita.com/Junpei_Takagi/items/603d44f7885bd6519de2)を参考にすると良いです。

# Vueプロジェクト起動

``` console
$ docker-compose exec web yarn serve
```



# フロント側の疎通確認

ブラウザで「[http://localhost](http://localhost)」にアクセスしてwelcomeページが出たらOK
![スクリーンショット 2024-01-26 10.15.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647483/d0808b1e-978d-3322-e47c-d98da24c2e34.png)



# API側の疎通確認

``` php:api/routes/api.php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

// 追加
Route::get('/test', function() {
    return response()->json([
        'message' => 'API test.',
    ]);
});

```

``` console
$ curl -X "GET" "http://127.0.0.1/api/test"
{"message":"API test."}
```
JSONが返ってきていたらOK

# 参考
https://qiita.com/nagi125/items/09ddbbfa923c0999494e

https://qiita.com/Junpei_Takagi/items/603d44f7885bd6519de2