EC2にDocker(Laravel + Mysql + phpmyadmin + nginx)を構築

#【EC2】【Docker】Laravel + Mysql + phpmyadmin + nginx　環境構築#


#目次
[1.はじめに](#1-はじめに)
[2.目的](#2-目的)
[3.Dockerのインストール](#3-dockerのインストール)
[4.Docker-composeのインストール](#4-docker-composeのインストール)
[5.Dockerfilelを書く](#5-dockerfileを書く)
[6.docker-compose.ymlを書く](#6-docker-composeymlを書く)
[7.Laravelのインストール](#７-laravelのインストール)
[8.まとめ](#8-まとめ)

#1. はじめに
初めまして、Deliaと申します。
社会人2年目のネットワーク(サーバ)エンジニアです。
かなり前からWeb開発に興味が有り、時間的に余裕ができたので勉強を始めました。
そんな初心者がDockerを用いたLaravel環境構築の手順を備考録としてまとめました。
手順抜けや意味のない設定等あるかもしれません。
その際はご指摘いただけますと幸いです。


実行環境
PC：__Macbook Pro__
OS：__Big Sur 11.2.2__
EC2：__Amazon Linux 2__
Docker：__Docker version 19.03.13-ce, build 4484c46__
docker-compose：__docker-compose version 1.16.1, build 6d1ac21__



#2. 目的
EC2のVPC上にDockerを用いて以下を構築する。
 ・Laravel
 ・Mysql
 ・phpMyadmin
 ・Nginx

最終的な構造は以下のようになります。

```shell
 Docker/
　   ├ php/
　   │　└ src/
　   │　│  └ Laravel/
　   │　└ php.ini
　   │　└ Dockerfile
　   ├ web/
　   │　└ default.conf
　   │　└ Dockerfile
　   ├ db/
　   │　└ init.d/
　   │　│  └ 初期化に使うSQLとか
　   │　└ data/
　   │　│  └ データベースのデータ
　   │　└ Dockerfile
　   └ phpmyadmin/
　    　└ sessions/
　    　└ Dockerfile
```

#3. dockerのインストール
公式を参考にインストールしていきます。


```shell:EC2
sudo yum update                                    # とりあえず
sudo amazon-linux-extras install docker            # Dockerをインストールする
sudo usermod -a -G docker ec2-user                 # ec2-userがコマンドを使えるように願いを込める
sudo service docker start                          # 起動する
docker info                                        # 確認する
```
[Extras Libraryについてはこちら](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-install-extras-library-software/)
[Dockerのインストールについてはこちら](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html)
#4. docker-composeのインストール
同様に、公式を参考にインストールする。
バージョンが表示されれば成功です。

```shell:EC2
sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose        # 権限を付ける
docker-compose --version                           # 確認する
```
[Docker-composeドキュメントはこちら](https://docs.docker.jp/compose/install.html)

#5. dockerfileを書く
今回はイメージは使用せず構築します。
まずはディレクトリを作成します。
それぞれのフォルダにDockerfileを作成します。

```shell:EC2
mkdir php db web phpmyadmin  
mkdir php/src db/init.d db/data
```
WebサーバにNginxを使用する場合phpは「___fpm___」バージョン？を使用します。
php用はLaravelインストールの為パッケージを追加します。

```dockerfile:Dockerfile　php用
FROM php:8.0.3-fpm-buster

RUN apt-get update \
 && apt-get install -y --no-install-recommends \
  libzip-dev \
  unzip \
  git \
 # phpがmysqlに接続するのに必要なドライバ
 && docker-php-ext-install pdo_mysql        
# Composerのインストール   
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
```
```dockerfile:Nginx用
FROM nginx:latest

COPY ./default.conf /etc/nginx/conf.d/default.conf
```
```dockerfile:Dockerfile　Mysql用
FROM mysql:latest
```
```dockerfile:Dockerfile　phpmyadmin用
FROM phpmyadmin:latest
```
ついでにNginxで使用するdefault.confを作成します。

```shell:EC2　/db/default.conf
server {
    listen       80;
    listen  [::]:80;
    root /var/www/html/Laravel/public;
    index index.php index.html index.htm;

    access_log  /var/www/html/access.log;
    error_log   /var/www/html/error.log;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass   php:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
        try_files $uri $uri/ /index.php$is_args$args;
    }
}
```

#6. docker-compose.ymlを書く

```yaml:docker-compose.yml
version: "3"
services:
  php:
    build: ./php/
    volumes:
      - ./php/src:/var/www/html
    container_name: php
    tty: true
  nginx:
    build: ./web/
    volumes:
      - ./php:/var/www/html         # Laravelがあるディレクトリをマウント
    container_name: nginx
    ports:
      - 8080:80                     # EC2のセキュリティグループで8080開放しておく
    depends_on:
      - php                         # phpが起動してから起動する
  mysql:
    build: ./db/
    volumes:
      - ./db/init.d:/docker-entrypoint-initdb.d   # イメージをbuildする際に実行される　初期データを作成するSQLファイル等を置いておく
      - ./db/data:/var/lib/mysql                  # 作成したテーブル等を永続させる場合に必要　※１
    container_name: mysql
    environment: 
      MYSQL_USER: yourname
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: root
    ports:
      - 3306:3306
    depends_on:
      - nginx
  phpmyadmin:
    build: ./phpmyadmin/
    volumes:
      - ./phpmyadmin/sessions:/sessions
    container_name: phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql
    ports:
      - 10080:80
    depends_on:
      - mysql
```

※１・・・権限の問題だと思いますが、一度ビルドしてから、ダウンして、データがホストに残っている状態で再度ビルドしようとすると弾かれます。ファイルの所有者が「libstoragemgmt」になっている為？
なので私はビルドする前にdocker-composeを実行するユーザをファイルの所有者に変更し、回避しています。
そもそも頻繁にビルドするものなのか？と思っています。
ここらへんがよくわからないので知っている方いましたらご教示いただけますと幸いです。


#7. laravelのインストール
　__1.コンテナを起動する__

```shell
docker-compose up -d --build
```
　__2.Laravelをインストールする__

```shell:Laravelのコンテナ
composer create-project laravel/laravel --prefer-dist YourProjectName
```
　__3.権限を変更する__
↓をしないとNginxがLaravelにアクセスできずエラーになります。
また、Mysqlもデータを永続化させる場合には権限周りをうまくやらないといけないみたいです。（6-※1）


```shell:Laravelのコンテナ
chown www-data Laravel/storage
chown www-data Laravel/vendor
```
  __4.ブラウザからアクセスして確認する__
![Laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1216302/b5d0d73b-af06-06d5-fa8b-b4148295aed5.png)

  __5.データベースの作成__
ここで作成したデータベース名を覚えておいてください。

```shell:EC2
docker-compose exec mysql bash
```
```shell:mysqlのコンテナ
mysql -u root -p
root
#Laravel_DB という名前のデータベースを作成します
CREATE DATABASE Laravel_DB
```

  __6.LaravelとMysqlの接続__
以下２ファイルを書き換えます。
database nameは先程のデータベース名を入力します。

```Laravel/.env
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=[database name]
DB_USERNAME=[user name]
DB_PASSWORD=[password]

```

```Laravel/config/database.php
'database' => env('DB_DATABASE', '[database name]'),
'username' => env('DB_USERNAME', '[user name]'),
'password' => env('DB_PASSWORD', '[password]d'),
```
 __7.接続の確認__
phpコンテナに入りファイルが正しく設定できているか、データベースと接続できるか確認します。

```shell:EC2
docker-compose exec php bash
```
```shell:phpのコンテナ
cd Laravel                # Laravelをインストールしたディレクトリに移動
php artisan tinker
DB::connection()
DB::select('SELECT * from users');
#------あらかじめテーブルを作成しておき、作成したデータを取得できればOK-------
=> [
     {#3337
       +"id": 1,
       +"name": "test",
       +"created_at": "2021-03-28 21:18:58",
       +"updated_at": "2021-03-28 21:18:58",
     },
   ]

```


# 8.まとめ

これで目的は達成できたのではないでしょうか。
まだまだ理解の足りない箇所がありますが、コンテナの作成、起動、コンテナ間の通信、連携ができました。
今後はそれぞれをより実務的な環境で構築できるよう学びたいです。
最後まで読んでいただきありがとうございました。