Dockerを使ってLaravelの開発環境を構築する

# 環境
Windows 10
Docker version 20.10.7

# プロジェクトを作成
プロジェクト用ディレクトリを作成＆移動

```bash:wsl
mkdir laravel
cd laravel
```

プロジェクト作成用のDockerfileを作成

```bash:wsl
mkdir -p docker/composer
touch docker/composer/Dockerfile
```

```Dockerfile:Dockerfile
FROM php:7.4-fpm
WORKDIR /application
RUN apt-get update && apt-get install -y \
            git \
            zip \
            unzip \
    && curl -sS https://getcomposer.org/installer | php \
    && mv composer.phar /usr/local/bin/composer
```
イメージをビルド

```bash:wsl
docker build -t laravel/composer:latest -f ./docker/composer/Dockerfile .
```
イメージを使用してプロジェクトを作成

```bash:wsl
docker run -v $(pwd):/application laravel/composer:latest composer create-project --prefer-dist laravel/laravel src "8.*"
```
srcディレクトリの中にプロジェクトが作成されます

```bash:wsl
$ ls src
README.md  artisan    composer.json  config    package.json  public     routes      storage  vendor
app        bootstrap  composer.lock  database  phpunit.xml   resources  server.php  tests    webpack.mix.js
```

#Laravelの動作環境を作る
## PHPコンテナ
Dockerfileを作成

```bash:wsl
mkdir docker/php
touch docker/php/Dockerfile
```

```Dockerfile:Dockerfile
FROM php:7.4-fpm

COPY ./src /application

WORKDIR /application

RUN apt-get update && apt-get install -y \
            git \
            zip \
            unzip \
    && curl -sS https://getcomposer.org/installer | php \
    && mv composer.phar /usr/local/bin/composer \
    && docker-php-ext-install pdo_mysql \
    && composer install

RUN php artisan cache:clear \
    && php artisan config:clear \
    && php artisan route:clear \
    && php artisan view:clear

RUN chown -R www-data:www-data storage
```
## nginxコンテナ
Dockerfileを作成

```bash:wsl
mkdir docker/nginx
touch docker/nginx/Dockerfile
```

```Dockerfile:Dockerfile
FROM node:14.11.0 as node-build

COPY ./src /application

WORKDIR /application

RUN apt-get update \
    && npm install \
    && npm run prod

FROM nginx:1.19.2

WORKDIR /application

RUN apt-get update

COPY ./docker/nginx/ecs/conf.d/default.conf /etc/nginx/conf.d/default.conf
COPY --from=node-build /application/public /application/public/

EXPOSE 80
```
設定ファイルを作成

```bash:wsl
mkdir docker/nginx/conf.d
touch docker/nginx/conf.d/default.conf
```

```conf:default.conf
upstream php-fpm {
    server php:9000;
}

server {
    listen 80;
    server_name localhost;
    root /application/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-TypeOptions "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }

    location = /robots.txt { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass php-fpm;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
```
## MySQLコンテナ
初期データの用意

```bash:wsl
mkdir -p docker/mysql/initdb.d
touch docker/mysql/initdb.d/01_init_db.sql
touch docker/mysql/initdb.d/02_insert_data.sql
```

```SQL:01_init_db.sql
CREATE SCHEMA IF NOT EXISTS laravel;
USE laravel;

CREATE TABLE users
(
  id           INT(10),
  name     VARCHAR(40)
);
```

```SQL:02_insert_data.sql
INSERT INTO users (id, name) VALUES (1, "Dog");
INSERT INTO users (id, name) VALUES (2, "Cat");
```

.envファイルの変数を書き換え

```.enf:/src/.env
DB_HOST=mysql
DB_USERNAME=admin
DB_PASSWORD=password

```

## Docker Compose
docker-compose.ymlの作成

```bash:wsl
touch docker-compose.yml
```

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

services:
    php:
        build: 
            context: .
            dockerfile: ./docker/php/Dockerfile
        volumes:
            - ./src:/application
            - /application/vendor
        env_file: 
            - .env
    nginx:
        build: 
            context: .
            dockerfile: ./docker/nginx/Dockerfile
        volumes:
            - ./docker/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
        ports:
            - 80:80
        depends_on:
            - php
        env_file: 
            - .env
    mysql:
        image: 'mysql:8.0'
        ports:
            - ${DB_PORT}:3306
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
        volumes:
            - ./docker/mysql/initdb.d:/docker-entrypoint-initdb.d
```

ビルド

```bash:wsl
docker-compose --env-file ./src/.env up
```
# 動作確認
localhostにアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/8941ecc7-d9b5-8010-2eec-1312efc1c4cd.png)

DBとの接続確認

```bash:wsl
docker exec -it laravel_php_1 bash
php artisan tinker
DB::select('SELECT * FROM users')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/dabfc21b-08e8-3421-a142-5066c228f905.png)