Docker × Laravelでプロジェクトを作成する 前半

この記事ではDocker上にLaravelプロジェクトを立ち上げる方法を解説していきます。
今回の記事を理解する上で大事な用語が多いですが、随時解説していきますので安心してついてきてくださいね！

なお、自分のPCは
・MacBook Pro
・M2チップ
なので、予めご了承ください

## まずはDockerのインストールから
なにはともあれ、まずはDockerのインストールをしないと始まらないので、
[公式サイト](https://www.docker.com/get-started/)から、ご自身のOS用のDockerをダウンロードしてください。
DockerDesktopをインストールしてくださいね。Docker Hubの方ではないので注意してくださいね。
指示通りインストールできたらターミナルを開いて
```
docker version
```
と叩いて、Dockerに関する情報が出てきたらインストールは無事完了です！

Macをお使いの方で何か不具合があったら、再起動することで動くことがあるので試してみてください！

## 実際にDocker上にLaravelプロジェクトを作成
まず適当なディレクトリを作成してください。
ぼくは`practice`というディレクトリを作成しました。

次に、作成したディレクトリの中に`docker`ディレクトリを作成します。

```
practice
    docker
```
ここまでは大丈夫でしょうか？

### dockerイメージの作成
新たな言葉が出てきました。
手を動かしながら説明していきます

先ほど作成したdockerファイルに３つのフォルダを作成してきます
```
practice
    docker
        app
        db
        web
```
`app`と`db`と`web`というディレクトリを作成してください。
そしたら、それぞれのディレクトリに`Dockerfile`を作成してください。
それ以外のファイルも少し作成します。
```
practice
    docker
        app
            Dockerfile
            php.ini
        db
            Dockerfile
            my.cnf
        web
            Dockerfile
            default.conf
```
この`Dockerfile`に記述された内容によってdockerイメージが作成されていきます
#### Dockerイメージ
dockerイメージはコンテナの中で使われます
ちなみにコンテナに関しては前の記事で解説していますので、よくわからない方は[そちら](https://qiita.com/wangqijiangjun/items/7e353cbae72ebfe0fd9a)もご覧ください。

**Dockerイメージとは、コンテナ内で動かすDBやアプリケーションやメールサーバー等を作る際の設定ファイルのことです。**
これらのファイルによって、コンテナ内で動かすDBやアプリケーションやメールサーバー等が作成されます。

まず、`app`ディレクトリ内の`Dockerfile`を作成していきます。
その作成した`Dockerfile`に以下のコードを記述します

```
FROM php:8.0-fpm

ENV TZ Asia/Tokyo

RUN apt-get update && \
	apt-get install -y git unzip libzip-dev libicu-dev libonig-dev && \
	docker-php-ext-install intl pdo_mysql zip bcmath
		
COPY ./docker/app/php.ini /usr/local/etc/php/php.ini

COPY --from=composer:2.0 /usr/bin/composer /usr/bin/composer

WORKDIR /app
```

ちゃんと理解していくために、1行1行読み解いていきます。

##### FROM
`FROM`は、Dockerイメージ（コンテナ内で動かすDBやアプリケーションやメールサーバー等を作る際の設定ファイルのこと）のベースイメージを指定します。
今回は、`Laravel`のプロジェクトを作成するので、`PHP`を指定していますが、`Rails`プロジェクトを作成するときは、`Ruby`を指定する必要があります。
また、ベースイメージのバージョンも指定することができます。

原則として、`Dockerfile`の１番上に記述する必要があります。

##### ENV
このコマンドでは、環境変数を指定していいます。
環境変数とは、OSが持つ変数のことです。

##### RUN
`RUN`コマンドは、ビルド時に実行されるコマンド自体を指定しています。
ここで指定されるコマンドは、ぼくの主観ではありますが、`Linux`コマンド自体が多いように感じます。

１だけ取り上げますがここでは、`apt-get update`コマンドが指定されています。
このコマンドは、アップデートが可能なパッケージがあるかをチェックして、パッケージリストを更新するコマンドです。
`Dockerfile`がビルドされるときに、この処理が行われます。

##### COPY
`COPY`コマンドはローカルのファイルを`Docker`イメージのファイルシステムにコピーするコマンドです。
後ろの方で出てきますが、`php.ini`ファイルを作成し、それを`/usr/local/etc/php/php.ini`にコピーしますよ、というコマンドです。

##### WORKDIR
`WORKDIR`コマンドは、この`Dockerfile`を操作するパスを指定します。
今回のように、`Dockerfile`が複数ある場合、操作するパスを指定してあげることで、ビルドしたときのエラーを防ぐことができます。


`app`ディレクトリ下に`php.ini`ファイルを設定します。
そのファイルに以下のコードを書きます。
```
zend.exception_ignore_args = off
expose_php = on
max_execution_time = 30
max_input_vars = 1000
upload_max_filesize = 64M
post_max_size = 128M
memory_limit = 256M
error_reporting = E_ALL
display_errors = on
display_startup_errors = on
log_errors = on
error_log = /var/log/php/php-error.log
default_charset = UTF-8

[Date]
date.timezone = Asia/Tokyo

[mysqlnd]
mysqlnd.collect_memory_statistics = on

[Assertion]
zend.assertions = 1

[mbstring]
mbstring.language = Japanese
```
説明は省きますが、メモリサイズや、文字コードを指定しています。
環境設定をしています。

`db`ディレクトリの`Dockerfile`には以下のコードを記述します。

```
FROM mysql:8.0
```
先程の`FROM`コマンドを理解していれば、何をしているかわかると思います。

`my.cnf`ファイルには以下のコードを記述します。
```
[mysqld]
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci

default-time-zone = SYSTEM
log_timestamps = SYSTEM

log-error = mysql-error.log

slow_query_log = 1
slow_query_log_file = mysql-slow.log
long_query_time = 1.0
log_queries_not_using_indexes = 0

general_log = 1
general_log_file = mysql-general.log

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4
```

`web`ディレクトリの`Dockerfile`には以下のようなコードを記述してください。
```
FROM nginx:1.20-alpine

ENV TZ Asia/Tokyo

RUN chmod 755 -R /root

COPY ./docker/web/default.conf /etc/nginx/conf.d/default.conf
```

`default.conf`ファイルには以下のようなコードを記述してください。
```
server {
    listen 80;
    server_name example.com;
    root /app/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "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 app:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
```

これでDockerイメージを作成するためのファイルが完成しました。
これで目標のDocker上でLaravelのプロジェクトを作成するまでの手順の50%が終わりました！


次の記事では、`docker-compose`について説明していきます！

最後まで読んでいただきありがとうございました！

Twitterもやっているので、[こちら](https://twitter.com/KEI50800185)もご覧ください！



【参考文献】

https://docs.docker.jp/engine/reference/builder.html

https://www.tohoho-web.com/docker/command.html