LEMP環境でNext.js(TypeScript)とLaravel(PHP)を利用して、LEMP環境で勤怠管理アプリを作成してみる。〜Docker編〜


前回は、フロントエンドにNext.jsのフレームワーク、バックエンドにLaravelというフレームワークを組み込むやり方をしました。

次は、手動で、それぞれのブラウザを動かさないで、

Dockerという開発環境を使うだけで、フロントエンドとバックエンド両方を動かすようにしていきます。

使う環境は、LEMP(Linux、Nginx、MySQL、PHP)です。

Nginxは、大量のリクエストを効率的に処理でき、

メモリやCPUリソースの消費が少ないため、リソースが限られている環境でも優れたパフォーマンスを発揮します。

HTTPS通信のセキュリティ強化が簡単に行え、また、DDoS攻撃対策や不正アクセスの防止にも有効な設定が可能という利点があります。


# ディレクトリ構造

まず、プロジェクトのディレクトリ構造を以下のようにします
```
attendance
├── laravel         # Laravelプロジェクト
│   ├── Dockerfile
│   ├── docker
│   │   └── php
│   │       ├── php.ini
│   ├── .env
│   └── ... (Laravelファイル)
├── frontend        # Next.jsプロジェクト
│   ├── Dockerfile
│   ├── .env.local
│   └── ... (Next.jsファイル)
├── nginx           # Nginx設定ファイル
│   ├── default.conf
├── docker-compose.yml # Docker Compose構成ファイル
└── mysql           # MySQLデータ永続化用のディレクトリ

```

## Laravel用のDockerfile

```dockerfile:laravel/Dockerfile

FROM php:8.2-fpm

# 必要なライブラリとPHP拡張のインストール
RUN apt-get update && apt-get install -y \
    git \
    unzip \
    libpq-dev \
    libjpeg-dev \
    libpng-dev \
    libfreetype6-dev \
    libonig-dev \
    && docker-php-ext-configure gd \
    && docker-php-ext-install pdo_mysql mbstring gd

# Composerのインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

# 権限設定
RUN chown -R www-data:www-data /var/www/html

CMD ["php-fpm"]
```

## Next.js用のDockerfile
attendance/frontend/Dockerfile
```dockerfile:frontend/Dockerfile

FROM node:18

WORKDIR /usr/src/app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000
CMD ["npm", "run", "dev"]
```

## Nginxの設定

```conf:attendance/nginx/default.conf
server {
    listen 80;

    # Laravel APIバックエンド
    location /api {
        proxy_pass http://laravel:9000;
        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;
    }

    # Next.jsフロントエンド
    location / {
        proxy_pass http://frontend:3000;
        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;
    }
}
```

## Docker Compose設定

```yml:attendance/docker-compose.yml

version: '3.9'

services:
  laravel:
    build:
      context: ./laravel
      dockerfile: Dockerfile
    container_name: laravel
    volumes:
      - ./laravel:/var/www/html
    env_file:
      - ./laravel/.env
    depends_on:
      - db
    networks:
      - lemp

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    container_name: frontend
    volumes:
      - ./frontend:/usr/src/app
    env_file:
      - ./frontend/.env.local
    ports:
      - "3000:3000"
    networks:
      - lemp

  db:
    image: mysql:8.0
    container_name: mysql
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: laravel
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    ports:
      - "3306:3306"
    networks:
      - lemp

  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "8080:80"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./laravel:/var/www/html
      - ./frontend:/usr/src/app
    networks:
      - lemp

networks:
  lemp:
    driver: bridge
```

## Laravelの環境変数ファイル

laravelディレクトリ内にある.envファイルを以下のように変更してください。



```env:attendance/laravel/.env

APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8080/api

LOG_CHANNEL=stack

DB_CONNECTION=mysql # Dockerを動かしていない場合は、sqliteに戻す
DB_HOST=db  # Dockerを動かしていないときは、127.0.0.1に戻す
DB_PORT=3306 # Dockerを動かしていない時は # DB_PORT=3306に戻す
DB_DATABASE=laravel # Dockerを動かしていない時は # DB_DATABASE=laravelに戻す
DB_USERNAME=user   # Dockerを動かしていない時は # DB_USERNAME=userに戻す
DB_PASSWORD=password # Dockerを動かしていない時は # DB_PASSWORD=passwordに戻す
```


### 環境変数の使用

Next.jsのプロジェクトのルートディレクトリ（package.json が存在する場所）に移動します。

.env.local という名前のファイルを作成します。

API URL を環境変数で管理するため、.env.local ファイルに以下を追加します
```env:.env.local
NEXT_PUBLIC_API_URL=http://localhost:8080/api
```

.env.local の変更を反映するには、Next.js のサーバーを再起動する必要があります。

```
$ npm run dev
```

## MySQLデータ永続化の準備

Docker ComposeでMySQLのデータ永続化を行うため、attendance/mysql ディレクトリを作成します。Dockerが自動的にこのディレクトリを使用します。
```
$ mkdir attendance/mysql
```

## Docker Composeで環境を起動

以下のコマンドを実行してDocker Compose環境を構築・起動します。
```
$ docker-compose up -d --build
```
![新規メモ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945016/6b40200f-02cc-3373-f96f-1c24bf9a9705.jpeg)


上のような画面が表示されれば成功です。

## アクセス方法

ブラウザで、 http://localhost:8080 とコマンドを打ってみましょう。

すると、

![新規メモ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945016/8a83387d-fa85-5f16-652b-4ee11822bde6.jpeg)

という画面が出てきました。

フロントエンドは成功です。

次に、バックエンドである

Laravelが起動しているか確認です。

## Laravelのマイグレーション

Laravelコンテナに入って、マイグレーションを実行します。
```
$ docker exec -it laravel bash
$ php artisan migrate
```
これでデータベースが設定され、LaravelとNext.jsがDocker上で動作するLEMP環境が完成します。

MySQLのデータは attendance/mysql ディレクトリに保存されるため、コンテナを削除してもデータは消えません。

Laravelのブラウザは、 http://localhost:8080/api なので、このコマンドを打ってください。

すると、


![AD_4nXe70u7HQr1f6aeDYLNuUHa1M5vuI0pSVjl1GRIdstweSutct-yDIUW8gAP-kfVrwOFQuP_4Jfy_3HP3JJErIKnFKpIHkAnfX91CXUjmgPGs-flPDF6hu039.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945016/c277b116-9449-7de5-f2a1-0a93e079522d.jpeg)


という画面が出れば、成功です。

これで、開発環境は、整いました。

次回は、いよいよ勤怠管理アプリを作成していきます、↓

https://qiita.com/makkyo-git/items/c88ca8a7860a4b94be2c