Docker＋Amazon LinuxでLaravel開発環境を構築

Docker環境を作ってみよう！・・・と思い立ったので、コピペできるように纏めました。

# マシンスペック
* Mac mini 2018
* macOS Catalina（10.15.x）
* Intel Core-i7 3.2GHz 6コア
* メモリ 32GB
* SSD 512GB

# Docker環境
* Amazon Linux2
* Nginx 1.x
* PHP（PHP-FPM）7.1.x
* MySQL 5.7.x
* Laravel 5.x

# やること
* Dockerのインストール
* Amazon Linuxで環境構築
* Macからマウント

# 補足
各環境を行ったり来たりするので、下記のように記載します。

```
[Mac]$ MacのターミナルでMac内の作業
[Docker]$ Macのターミナルからコンテナに接続して作業
[Docker]# Macのターミナルからコンテナに接続してroot権限で作業
```

# 前提
Homebrewはインストール済み

※参考
[macOS（またはLinux）用パッケージマネージャー — Homebrew](https://brew.sh/index_ja)

#Dockerのインストール

Home brewでインストールします。

```
[Mac]$ brew install --cask docker
Updating Homebrew...
〜 省略 〜
==> Downloading https://desktop.docker.com/mac/stable/45519/Docker.dmg
######################################################################## 100.0%
==> Verifying SHA-256 checksum for Cask 'docker'.
==> Installing Cask docker
==> Moving App 'Docker.app' to '/Applications/Docker.app'.
🍺  docker was successfully installed!

[Mac]$ open /Applications/Docker.app
```

タスクバーのDockerアイコンが「Docker Desktop is running」になるまで待つ。
下記の画面が表示されるが、閉じて良い。
<img width="1044" alt="スクリーンショット 2020-07-01 17.15.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111551/041d4ad0-dac5-77db-994e-0e865f33464a.png">

### 動作確認
```
[Mac]$ which docker
/usr/local/bin/docker

[Mac]$ docker --version
Docker version 19.03.8, build afacb8b

[Mac]$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete 
Digest: sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

〜 省略 〜

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

[Mac]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        5 months ago        13.3kB
```

※参考
[Homebrewを使ってDockerをMacにインストール](https://qiita.com/atahiro/items/61e826b4cb2387bcd226)

### hello-world削除
```
[Mac]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
5b8f790636cd        hello-world         "/hello"            3 minutes ago       Exited (0) 3 minutes ago                       unruffled_villani

[Mac]$ docker rm 5b8f790636cd
5b8f790636cd

[Mac]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        5 months ago        13.3kB

[Mac]$ docker rmi bf756fb1ae65
Untagged: hello-world:latest
Untagged: hello-world@sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b
Deleted: sha256:9c27e219663c25e0f28493790cc0b88bc973ba3b1686355f221c38a36978ac63
```

※参考
[Dockerイメージとコンテナの削除方法](https://qiita.com/tifa2chan/items/e9aa408244687a63a0ae)

# コンテナの起動
### イメージのダウンロード
```
[Mac]$ docker pull amazonlinux:2
2: Pulling from library/amazonlinux
a3f8e652bdc4: Pull complete 
Digest: sha256:436544dbd50a2f1f876390b9c2b09e98d73badb222ba188d69d58e649aa1b6b3
Status: Downloaded newer image for amazonlinux:2
docker.io/library/amazonlinux:2

[Mac]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
amazonlinux         2                   7f335821efb5        2 months ago        163MB
```

### Systemdパッケージをインストールする為にコンテナ起動

コンテナ内でsystemctlコマンドを利用する為には、コンテナを/sbin/initで起動する必要がある。
AmazonLinux2のイメージが、初期状態だと/sbin/initできない為、まずはコンテナにSystemdパッケージをインストールする。

```
[Mac]$ docker run -it -d --privileged --name local -p 8080:80 amazonlinux:2 /bin/bash
[Mac]$ docker exec -it local /bin/bash
bash-4.2# 

[Docker]# yum -y install systemd
[Docker]# exit
```

※参考
[Docker上のAmazonLinux2でLaravelの環境構築](https://qiita.com/skyknsk/items/c9710bb952a854a32cfd)

### Systemdパッケージをインストールしたコンテナをイメージ化
```
[Mac]$ docker commit local amazonlinux:local
[Mac]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
amazonlinux         local               20a6c14cc93c        20 seconds ago      422MB
amazonlinux         2                   7f335821efb5        2 months ago        163MB
```

### コンテナ停止
```
[Mac]$ docker stop $(docker ps -q)
```

※参考
[コマンドでDockerコンテナを停止・削除、イメージの削除をする](https://qiita.com/shisama/items/48e2eaf1dc356568b0d7)

### コンテナ起動
```
[Mac]$ docker run --privileged -d -p 8080:80 --name amazonlinux amazonlinux:local /sbin/init
67f478ad9855289bd0c041cfde25869ec79d007bb222ee52905287aef565777c
[Mac]$ docker exec -it amazonlinux /bin/bash
bash-4.2# 
```

# コンテナ作業あれこれ（インストールとか）
### yumあれこれ
```
[Docker]# yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
[Docker]# yum -y install epel-release
[Docker]# yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
[Docker]# yum -y update
[Docker]# yum -y install yum-utils
[Docker]# sed -i -e "s/priority=10/priority=99/g" /etc/yum.repos.d/amzn2-core.repo
```

#### ユーザー作成
```
[Docker]# useradd docker
[Docker]# ls /home
docker
```

#### sudo設定
```
[Docker]# yum install -y sudo
[Docker]# visudo

★下記の点線内を追記
---
docker ALL=(ALL)       NOPASSWD: ALL
---
:wq
```

#### PHPのインストール
```
[Docker]# yum-config-manager --enable remi-php71
[Docker]# yum -y install --enablerepo=remi,remi-php71 php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt php-mysqlnd php-fpm php-pecl-xdebug php-pecl-zip php-bcmath
```

#### Nginxのインストール
```
[Docker]# vi /etc/yum.repos.d/nginx.repo
★点線内をコピペ
---
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
enabled=0
gpgcheck=0
---
:wq
[Docker]# yum -y --enablerepo=nginx install nginx
```

#### PHPの設定
```
[Docker]# vi /etc/php.ini
★点線内を末尾（Gで移動）にコピペ
---
xdebug.remote_enable = On
xdebug.remote_autostart = On
xdebug.remote_connect_back = 1
xdebug.remote_port = 9000
xdebug.scream = 0
xdebug.show_local_vars = 1
xdebug.idekey=PHPSTORM
---
:wq
```

#### PHP-FPMの設定
```
[Docker]# vi /etc/php-fpm.d/www.conf
★下記を点線内に編集
user = apache
group = apache
listen = 127.0.0.1:9000
;listen.owner = nobody
;listen.group = nobody
;listen.mode = 0660
↓
---
user = nginx
group = nginx
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
---
:wq
```

#### Nginxの設定
```
[Docker]# cd /etc/nginx
[Docker]# cp nginx.conf nginx.conf.org
[Docker]# cd /etc/nginx/conf.d
[Docker]# cp default.conf default.conf.org
[Docker]# vi /etc/nginx/conf.d/default.conf
★点線内に置き換え
---
server {
    listen 80;
    server_name laravel.local;

    charset UTF-8;
    access_log  /var/log/nginx/access.log;
    location / {
        root /home/vagrant/laravel/public;
        try_files $uri /index.php?$query_string;
    }

    #error_page 404 /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504  /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    location ~ \.php$ {
        root /home/docker/laravel/public;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
---
:wq
```

##### PHP-FPMとNginxの起動および自動起動設定
```
[Docker]# systemctl start php-fpm
[Docker]# systemctl enable php-fpm
[Docker]# systemctl start nginx
[Docker]# systemctl enable nginx
```

#### MySQLのインストール、DB作成、ユーザー作成
```
[Docker]# rpm -Uvh https://repo.mysql.com/yum/mysql-5.7-community/el/7/x86_64/mysql57-community-release-el7-10.noarch.rpm
[Docker]# yum -y install --enablerepo=mysql57-community mysql-community-server
[Docker]# systemctl enable mysqld.service
[Docker]# systemctl start mysqld.service
[Docker]# grep 'temporary password' /var/log/mysqld.log
2020-06-26T09:21:06.925606Z 1 [Note] A temporary password is generated for root@localhost: XXXXXX
[Docker]# mysql_secure_installation
Enter password for user root: XXXXXX
★パスワードは「英字小文字、英字大文字、数字、記号」の組み合わせにしたら通る
 例）docker#DOCKER1234
New password: docker#DOCKER1234
Re-enter new password: docker#DOCKER1234
〜 以降の質問は全て y で回答 〜
All done!

[Docker]# mysql -u root -p
Enter password: docker#DOCKER1234

★DB：hoge、USER：fuga、PASSWORD：docker#DOCKER1234（※好きなのに変える）
mysql> create database hoge;
mysql> CREATE USER fuga@'%' IDENTIFIED BY 'docker#DOCKER1234';
mysql> GRANT ALL ON hoge.* TO fuga@'%';
mysql> CREATE USER fuga@'localhost' IDENTIFIED BY 'docker#DOCKER1234';
mysql> GRANT ALL ON hoge.* TO fuga@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> quit

[Docker]# vi /etc/my.cnf
★点線内を追記
---
character-set-server = utf8
default_password_lifetime = 0
---
:wq

[Docker]# systemctl restart mysqld.service
[Docker]# exit
```

※参考
[CentOS7.1にMySQL 5.7をインストール](https://qiita.com/ksugawara61/items/336ffab798e05cae4afc)

### ユーザー指定でコンテナに接続する
```
[Mac]$ docker exec -u docker -it amazonlinux /bin/bash
```

### コンテナ作業の続き
#### Laravelのインストールの準備
```
[Docker]$ cd ~
[Docker]$ curl https://getcomposer.org/installer | php
[Docker]$ sudo mv -i composer.phar /usr/local/bin/composer
[Docker]$ sudo yum -y install unzip
★Nginxが/home/docker配下を実行できるようにする
[Docker]$ chmod 701 /home/docker
[Docker]$ exit
```

### イメージ化
```
[Mac]$ docker commit amazonlinux amazonlinux:local2
```

### マウントする
```
[Mac]$ docker stop $(docker ps -q)
[Mac]$ docker rm $(docker ps -q -a)
[Mac]$ mkdir -p ~/Work/MountPoint/docker/mount
[Mac]$ docker run --privileged -d -p 8080:80 -v ~/Work/MountPoint/docker/mount:/home/docker --name amazonlinux amazonlinux:local2 /sbin/init
[Mac]$ docker exec -u docker -it amazonlinux /bin/bash
```

※参考
[【Docker】Dockerでホストのディレクトリをマウントする](https://qiita.com/Yarimizu14/items/52f4859027165a805630)

### コンテナ作業の続き其の弐
#### Laravelのインストール、設定
```
[Docker]$ cd ~
[Docker]$ composer create-project --prefer-dist laravel/laravel laravel "5.6.*"
[Docker]$ cd laravel
[Docker]$ composer require --dev barryvdh/laravel-ide-helper
[Docker]$ composer require --dev squizlabs/php_codesniffer
[Docker]$ chmod -R 777 storage
[Docker]$ chmod -R 777 bootstrap/cache

[Docker]$ vi .env
★下記を点線内に編集
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
↓
---
DB_DATABASE=hoge
DB_USERNAME=fuga
DB_PASSWORD=docker#DOCKER1234
---
:wq

[Docker]$ php artisan migrate
[Docker]$ php artisan db:seed

[Docker]$ mkdir bin
[Docker]$ vi bin/clear-laravel.sh
★下記を点線内をコピペ
---
#!/bin/bash
php artisan view:clear
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan clear-compiled
php artisan config:cache
composer dump-autoload
php artisan ide-helper:generate
php artisan ide-helper:models -N
php artisan ide-helper:meta
find . -name '._.DS_Store' -type f -ls -delete
---
:wq
[Docker]$ chmod 755 bin/clear-laravel.sh
[Docker]$ bin/clear-laravel.sh
```

### ブラウザで動作確認
http://localhost:8080/

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111551/3f735218-18a5-d1c0-d8dc-c433bf65cad7.png)