DevContainer+Laravelで爆速ローカル環境構築

# はじめに
本稿では使用している技術の説明は行いません。
各自で調べてください。
# 対象者
Docker、linux、devcontainerの基礎知識がある方
急ぎでLaravelをWebアプリケーションとしてサクッと構築したい方
最小設定内容を知りたい方
# ファイル作成
以下の構成となるようにファイルを作成してください。
```
project root
└── .devcontainer
    ├── container
    │   ├── apache
    │   │   ├── Dockerfile
    │   │   └── httpd.conf
    │   └── php
    │       └── Dockerfile
    ├── .env
    ├── docker-compose.yml
    └── devcontainer.json
```
## ファイル作成
### container/apache/Dockerfile
```
FROM httpd:2.4

CMD ["httpd", "-D", "FOREGROUND"]
```
### container/apache/httpd.conf
```
ServerRoot "/usr/local/apache2"
Listen 80

LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule dir_module modules/mod_dir.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule log_config_module modules/mod_log_config.so

ServerName localhost
User daemon
Group daemon

DocumentRoot "/var/www/html/public"
<Directory /var/www/html/public>
  AllowOverride All
  Require all granted
</Directory>

ProxyPassMatch "^/(.*\.php(/.*)?)$" "fcgi://app:9000/var/www/html/public/$1"

DirectoryIndex index.php index.html

ErrorLog /dev/stdout
CustomLog /dev/stdout combined
```
### container/php/Dockerfile
```
# ====== Node.js & npm をインストールするステージ ======
FROM node:20 as node_builder

WORKDIR /app

# npm の最新バージョンをインストール
RUN npm install -g npm@11.2

# ====== PHP + Laravel を構築するステージ ======
FROM php:8.4-fpm

# 必要なシステムライブラリをインストール
RUN apt-get update && apt-get install -y \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    libonig-dev \
    zip \
    unzip \
    curl \
    git \
    && docker-php-ext-install pdo_mysql mbstring bcmath gd

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

# Node.js & npm のみを PHP イメージにコピー
COPY --from=node_builder /usr/local/bin/node /usr/local/bin/node
COPY --from=node_builder /usr/local/bin/npm /usr/local/bin/npm
COPY --from=node_builder /usr/local/lib/node_modules /usr/local/lib/node_modules

# 既存の npm のリンクがない場合のみ作成
RUN [ ! -f /usr/local/bin/npm ] || rm -f /usr/local/bin/npm && \
    ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm

# 既に www-data ユーザーが存在するか確認し、存在しない場合のみ作成
RUN id www-data || useradd -m -d /home/www-data -s /bin/bash www-data

# www-data のデフォルトシェルを /bin/bash に変更
RUN usermod -s /bin/bash www-data

# www-data の権限を変更
RUN chown -R www-data:www-data /var/www/html && \
    chmod -R 755 /var/www/html

# www-data ユーザーでコンテナを実行
USER www-data

WORKDIR /var/www/html
```
### .env
```
# アプリ名
APP_NAME=laravel_base_model

# Apache コンテナのポート
WEB_PORT=8080
WEB_TLS_PORT=443

# DB周り
DB_HOST=mysql # DB_HOSTにはDBコンテナ名を入れる。
DB_PORT=3306
MYSQL_DATABASE=development
MYSQL_TEST_DATABASE=test
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_USER=user
MYSQL_PASSWORD=password
```
### docker-compose.yml
```
version: '3.8'

services:
  web:
    build: ./container/apache
    container_name: web
    restart: always
    ports:
      - ${WEB_PORT}:80
    volumes:
      - ../:/var/www/html
      - ./container/apache/httpd.conf:/usr/local/apache2/conf/httpd.conf
    depends_on:
      - app

  app:
    build: ./container/php
    container_name: app
    restart: always
    volumes:
      - ../:/var/www/html
    working_dir: /var/www/html
    environment:
      COMPOSER_ALLOW_SUPERUSER: 1
    depends_on:
      - db

  db:
    image: mysql:8.0
    container_name: db
    restart: always
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_ALLOW_EMPTY_PASSWORD: "no"
      MYSQL_RANDOM_ROOT_PASSWORD: "no"
    volumes:
      - db-data:/var/lib/mysql
    ports:
      - ${DB_PORT}:3306

volumes:
  db-data:
    driver: local

```
### devcontainer.json
```
{
    "name": "Laravel Base Model DevContainer",
    "dockerComposeFile": "docker-compose.yml",
    "service": "app",
    "workspaceFolder": "/var/www/html",
    "customizations": {
        "vscode": {
            "extensions": [
                "editorconfig.editorconfig", // エディタを跨いだ共通設定ファイルをVsCodeで実行するのに必要
                "ms-azuretools.vscode-docker", // VsCodeでのIntelliSenseやタブ補完用
                "xdebug.php-debug", // デバッガ
                "bmewburn.vscode-intelephense-client", // PHP インテリセンス
                "onecentlin.laravel-extension-pack", // Laravel用拡張機能群 https://zenn.dev/na9/articles/23c18a0d2d8ee2#12%E5%80%8B%E3%81%AE%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD%E3%81%9F%E3%81%A1
                "spywhere.guides", // インデントを見やすくする
                "streetsidesoftware.code-spell-checker", // タイポチェック
                "mosapride.zenkaku", // 全角の強調表示
                "mhutchie.git-graph", // git
                "donjayamanne.githistory" // git
            ]
        }
    }
}

```
# 環境構築手順
1 Dockerをインストール
2 VsCodeをインストール
3 上記ファイルを作成
4 VsCodeの拡張機能にDevContainersをインストール
5 Ctrl Shift Pでコマンドパレットを開く
6 DevContainer:Reopen in Containerを押下
7 create projectコマンドを実行
特に理由はないが今回は8.0で作成
composer create-project laravel/laravel:^8.0 example-app

# 完成ソースコード
https://github.com/shrimptails-f/laravel_base_model