【Docker・Laravel】docker-composer.ymlとDockerfileの作り方。

[docker-composeを使ってDocker上にLaravelを構築する方法（Nginx & php-fpm & MySQL）](https://qiita.com/yuta-38/items/b3b370e25cca4823a046)で使った、docker-compose.ymlとDockerfileの中身について。



##docker-compoer.yml

```yml:docker-compoer.yml
version: '3'
services:

  #PHP Service
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: app_php-fpm
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network
    links:
      - webserver
      - db

  #Nginx Service
  webserver:
    image: nginx:alpine
    container_name: webserver
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/var/www
      - ./nginx/conf.d/:/etc/nginx/conf.d/
    networks:
      - app-network

  #MySQL Service
  db:
    image: mysql:5.7.22
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3307:3307"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: password
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - dbdata:/var/lib/mysql/
      - ./mysql/my.cnf:/etc/mysql/my.cnf
    networks:
      - app-network

#Docker Networks
networks:
  app-network:
    driver: bridge
#Volumes
volumes:
  dbdata:
    driver: local
```

・`version: '3'`
docker-composeはバージョンにより記述方法が異なる。基本的にはバージョン3を使用する。


<br>
##1. php-fpmのイメージとコンテナを作成
php-fpmのイメージとコンテナをサービス名appとして定義している。

```yml:docker-compoer.yml
#PHP Service
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: app_php-fpm
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network
    links:
      - webserver
      - db
```


###1-1. イメージのビルド
PHPサービスのイメージを作成するための記述は`build`と`image`。

`build`でイメージを作成し、作成したイメージ名を`image`で指定している。

```yml:docker-compoer.yml
    build:
      context: .
      dockerfile: Dockerfile
    image: app_php-fpm
```

イメージの作成にはDockerfileを指定している。
`context`で指定したパスから見て、`dokerfile`で指定した場所の中のDockerfileを探す。

####・contextディレクティブ
Dockerfileを探すために基準となるパスを指定する。必須項目。


####・dockerfileディレクティブ
dockerfileはファイル名の指定がなければ、**デフォルトで指定したディレクトリのDockerfileを探す**。

contextで指定した場所にDockerfileがある場合は記述しなくてもいい。

なので、上記設定は以下でも同じ動きになる。

```yml:
    build:
      context: .
    image: app_php-fpm
```


<br>
###1-2. Dockerfile

```Dockerfile:Dockerfile
FROM php:7.3-fpm

# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/

# Set working directory
WORKDIR /var/www

# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    locales \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl \
    libonig-dev \
    libzip-dev

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install extensions
RUN docker-php-ext-install pdo_mysql zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd

# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

# Copy existing application directory permissions
COPY --chown=www:www . /var/www

# Change current user to www
USER www

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
```


####・FROM イメージ名:タグ名
ベースとなるイメージを指定。
ここではphp:7.3-fpmを指定している。タグを指定していない場合はlatestとなる。

buildを実行すると、まずはローカルで指定したイメージを探し、なければdocker hubを探しにいく。


<br>
####・バンドル関連ファイルのコピー

```
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
```

・`COPY <ファイル１> <ファイル２>,,, <ディレクトリパス>`
指定したローカルのファイルをdockerのディレクトリにコピーする。


<br>
####・WORKDIR パス
コンテナ起動時の

```
# Set working directory
WORKDIR /var/www
```

**以降のコマンドCOPY、RUN、CMD、ENTRYPOINTを実行する大元となるDockerコンテナ内のディレクトリを指定**する。

コンテナ内に指定したディレクトリが存在しない場合は作成してくれる（エラーにならない）

<br>
**▼複数記述することも可能**
複数記述した場合は、そのディレクトリが追加され、ディレクトも移動してく。（cdコマンドみたいな感じ）

```
WORKDIR app
WORKDIR b
WORKDIR c
RUN pwd

//現在地
app/b/c
```

<br>
###Linux（Debian系）依存パッケージのインストール

```
# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    locales \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl \
    libonig-dev \
    libzip-dev
```


####・`apt`
Linux（DebianやUbuntuなど）のパッケージ管理コマンド。Advanced Package Toolの略。

####・`apt-get`
パッケージの操作・管理を行うコマンド。

####・`apt-get update`
インストール可能なパッケージの一覧を更新する。（一覧の更新のみでインストールはしない）

一覧は/etc/apt/sources.listにある。

####・`apt-get install`
sources.listに沿ってパッケージをインストール or アップデートする。
`-y`オプション：すべてyesを選択する。

| パッケージ | 内容 |
|:-:|:--|
| build-essential  | Debian系のOSを使うために必須  |
| libpng-dev  | png画像の読み込み・書き込み・編集  |
| libjpeg62-turbo-dev  | jpeg画像の読み込み・書き込み・編集  |
| libfreetype6-dev  | フォント関連の様々な操作をサポート（FreeType）  |
| locales  | 言語設定 |
| zip  | zip操作の圧縮。zipコマンドが使えるようになる  |
| jpegoptim  | jpg画像の圧縮  |
| optipng | png画像の圧縮（画質を下げることなく圧縮。圧縮率低め）  |
| pngquant   | png画像の圧縮（optipngよりも圧縮。画質は低下）  |
| gifsicle  | gif画像とアニメーションの読み込み・書き込み・編集  |
| vim | テキストエディタ  |
| unzip  | zip操作の解凍。unzipコマンドが使えるようになる  |
| git  | ソースコードなどの変更履歴を記録・追跡  |
| curl  | URLシンタックスを用いてファイルを送信または受信するコマンドラインツール  |
| libonig-dev  | 正規表現ライブラリ。鬼車（onigruma）  |
| libzip-dev  | zipアーカイブの読み取りと書き込み  |

Linux（Debian系）の構築や必要なコマンドライブラリを一気にインストール。

>・-devの意味
パッケージ名の後ろの`-dev`は、developmentの略。プログラム開発で必要なヘッダーやツール、ライブラリなどが入っている。



<br>
##aptのキャッシュ削除
apt-get installでパッケージをインストールすると、キャッシュが追加され容量が大きくなっていく。

キャッシュは不要なので削除する。

>ダウンロードしたパッケージは.deb形式で、var/cache/apt/ archives/ディレクトリに保存されます。これらのインストーラパッケージは、アンインストール後もローカルストレージに保持されます。

```
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
```

・`apt-get clean`
キャッシュを一掃する。

・`rm -rf /var/lib/apt/lists/*`
パッケージリストが削除する。apt-getで再度パッケージがインストールされたり、キャッシュファイルが増加するのを防ぐ。

**▼補足**
実行すると、パッケージに関する情報がないため、`apt-get install`はE: Unable to locate package <package>でエラーを返す。

`apt-get update`を実行すればリストが復活する。



<br>
##PHP拡張機能（エクステンション）のインストール

```
# Install extensions
RUN docker-php-ext-install pdo_mysql zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd
```

####・`docker-php-ext-install`
DockerにPHPの拡張機能をインストールするためのコマンド。

####・インストールする拡張機能

| PHP拡張機能 | 内容 |
|:-:|:--|
| pdo_mysql  | PHPからMySQLへのアクセスを可能にする  |
|  zip | zipのアーカイブとその内部のファイルに対する透過的な読み書きを可能にする  |
| exif  | 画像のメタデータ扱えるようになる。画像のヘッダ情報を読み込むなど  |
| pcntl  | プロセス制御機能。プロセスの並行処理を行う  |
| gd  | 画像をPHPスクリプトで生成する。画像のリサイズやグラフ作成などの描画機能を持たせることができる。  |


####docker-php-ext-configure
`docker-php-ext-configure <拡張機能> <オプション>`

指定した拡張機能の環境設定をする。環境設定は各拡張機能に割り当てられたオプションを使う。


####GDの主要オプション

```
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
```

GDの環境設定をしている。jepgやpngを使うGDをビルドするためにはlibpegやfreetype, libpngが必要なためインストールの設定をする。

| オプション | 意味 |
|:-:|:-:|
|  --with-gd[=DIR]  | GDライブラリの保存場所を指定  |
| --with-jpeg-dir[=DIR]  |  libjpegの保存場所  |
| --with-freetype-dir[=DIR] | FreeType 2の保存場所  |
| --with-png-dir[=DIR]  | libpngの保存場所   |


次の行でGDをインストール。

```
RUN docker-php-ext-install gd
```


#####GDインストール時の注意点
PHP7.4以降からGDインストール時のオプションが変更となっている。(上記設定だとエラーが出る)

>configure: error: unrecognized options: --with-gd, --with-freetype-dir, --with-jpeg-dir, --with-png-dir

PHP7.4以降は引数での環境設定が不要になる。必要なパッケージは`apt-get install`でインストールしておく。

なので、`docker-php-ext-config gd ~`は不要。

```:修正後
# Install extensions
RUN docker-php-ext-install pdo_mysql zip exif pcntl
RUN docker-php-ext-install gd
```


<br>
###composerのインストール

```
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
```

####・`curl -sS`
`-s`オプション
--silent。通常表示される進捗状況を表示しない。エラーメッセージも表示しない。

`-S`オプション
--show-error。エラーメッセージを表示する。-sとセットで使うことでエラーを表示する。

> curl --helpでオプション一覧が確認可能。


####・`curl -sS https://getcomposer.org/installer`
composerのinstallerをダウンドロードする。（composer-setup.phpを取得）

####・`|`
`コマンドA | コマンドB`

パイプライン。コマンドAの実行結果をコマンドBに渡す。

####・`php -- --install-dir=/usr/local/bin --filename=composer`
`php [options] -- [args...]`なので、引数で、インストール先のディレクトリとファイル名を指定。

- --install-dir=/usr/local/bin
- -filename=composer


<br>
###ユーザーとグループの追加

```
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
```

####・groupadd
groupaddコマンドで新しいグループ

```
groupadd [オプション] [グループID] <グループ名>
```

`-g`: --gidと同じ。作成するグループのID（GID）を指定。 
指定がない場合は、未使用の番号を自動で割り振る。



<br>
**▼作成したグループの確認**
グループの情報は /etc/group に保存されている。コンテナの中で確認できる。

```
$ docker exec -it app bash
www@a1984dd1d4a4:/var/www$ cat /etc/group
www:x:1000:
```

・`①グループ名:②PW:③GID[④:所属メンバー名]`

1. グループ： www
2. PW： x （セキュリティのため表示されない。設定なしの場合は*）
3. GID: 1000
4. 所属メンバー：なし


<br>
####・useradd
useraddコマンドは新規ユーザーを作成し、ユーザーごとの設定ができる。

コマンドは長いが、最初のuseraddと最後のwww以外はすべてオプション。

```
useradd [オプション] ユーザー名
```

`-u`: ユーザーID（UID）の指定 
指定がない場合は、未使用の番号を自動で割り振る。

`-m`: ユーザーのhomeディレクトリが存在しない場合に作成。
指定しない場合は、「/」配下にユーザー情報が保存される。

`-s [dir]`: ユーザーのログインシェルをフルパスで指定（指定しなかった場合はデフォルト設定）

`-g [グループ名/gid]`: 指定したユーザーをグループに追加する。


<br>
**▼作成したユーザー情報の確認**
ユーザー情報は /etc/passwd に保存されている。コンテナの中で確認できる。

```
$ docker exec -it app bash
www@a1984dd1d4a4:/var/www$ cat /etc/passwd
www:x:1000:1000::/home/www:/bin/bash
```

・`①ユーザー名:②PW:③UID:④GID::⑤/home/<ユーザー名>:⑥シェルのパス`

1. ユーザー名： www
2. PW： x （セキュリティのため表示されない。設定なしの場合は*）
3. UID: 1000
4. GID: 1000
5. ユーザーのホームディレクトリ: home/www
6. ユーザーが使用するシェル： /bin/bash


<br>
###ローカルのPJをコンテナ内にコピー & ファイルオーナーの変更

```
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
```

・`COPY [--chown=<user>:<group>] <ローカルdir> <コンテナdir>`

ローカルの「.」をコンテナ内の「/var/www」にまるごとコピー。ユーザー名をwww、グループ名をwwwに変更。


<br>
###ユーザー名を指定

```
# Change current user to www
USER www
```

・`USER <user名 or uid>[:<group名 or gid>]`



 <br>
###ポート開放とphp-fpmの起動

```
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
```

####・`EXPOSE ポート番号`
指定したポートでリッスン（外部からのアクセスに備えて待機）する。

ここでは、php-fpmの9000番ポートを開けておく。

####・`CMD [`コマンド`, `引数１`, `引数２`,,,]`
CMDはコンテナ実行時のデフォルト処理を定める。Dockerfileに必須。記述は１つのみ。

php-fpmコマンドを実行して、php-fpmを起動。

<br>
以上がDockerfileの中身。
php:7.4-fpmイメージをベースに、必要なパッケージをインストール、ユーザー名や権限変更をしたのち、9000番ポートを開けてphp-fpm起動するイメージが出来上がり。


<br>
###イメージ名の設定
最後に作成したイメージに名前をつけて完了。（ここではapp_php-fpm）

```
image: app_php-fpm
```

（参考）[Dockerfile リファレンス](https://docs.docker.jp/engine/reference/builder.html#entrypoint)




<br>
##1-3. コンテナの設定
1-2までがイメージのビルド。続いてコンテナ起動時に実行される処理の確認。

```yml:docker-compose.yml
    #php-fpmサービスの続き
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network
    links:
      - webserver
      - db
```

###container_name: コンテナ名
コンテナを作成した時の名前。起動・停止・削除に使うのでわかりやすく短めの名前がおすすめ。


###restart: コンテナ停止時の処理フラグ
コンテナが停止した時の処理をフラグで指定する。

| フラグ | 意味 |
|:-:|:--|
| no  | 再起動しない。デフォルト  |
| on-failure  | エラー発生時にコンテナを再起動（終了コードがゼロ以外）|
| always  | 常に再起動。手動で停止時はDockerデーモンが再起動した場合にコンテナを起動する  |
| unless-stopped  | 手動停止時を除いて再起動。Dockerデーモンを起動しても再起動しない。  |

**▼再起動ポリシー**

- コンテナ起動後が10秒以上立たない場合は自動再起動しない。（再起動ループを避ける）
- 手動でコンテナを停止すると、Dockerデーモンを再起動するか、コンテナを手動で再起動するまで再起動ポリシーを無視する。（再起動ループを避ける）
- 再起動ポリシーを適用できるのはコンテナのみです。(swarm サービスは対象外)

＞[Docker公式 restart](https://docs.docker.jp/config/container/start-containers-automatically.html)


####・`tty: <boolean>`
疑似ターミナル (pseudo-TTY) の割り当て。
`tty: true`で、ポート開放していないコンテナも起動状態をキープできる。（ないとコンテナがすぐに終了してしまう）

`docker exec`コマンドでコンテナに入って操作する際に必要。



<br>
###environment
環境変数の設定。
書き方は２種類。`Key: Value`または、`- Key=Value`。

```yml:
environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
```

以下と同じ。

```yml:
environment:
     - SERVICE_NAME=app
     - SERVICE_TAGS=dev
```

- **値を指定しない場合は、シェルの値を適用**する。
- DockerfileのARGやENVで指定した環境変数と被る場合は、**docker-composeの環境変数が優先**される。
- `env_file`で読み込んだ環境変数と被る場合は、**environment**が優先される。

<br>
**▼環境変数の優先度**

1. environment
2. env_file
3. DockerfileのARG, ENV

>env_fileは環境変数を定義したファイルを指定する。たくさんの環境変数を一括で読み込む場合に便利。

```.env:.env_fileの例
    env_file:
     - ./Docker/api/api.env
```

＞[Docker-compose における環境変数](https://docs.docker.jp/compose/environment-variables.html)

<br>
###working_dir
コンテナ内のデフォルトの作業用ディレクトリを指定する。

```yml:
 working_dir: /var/www
```

コンテナに入ると/var/wwwに入る。ここはプロジェクトがコピーされるディレクトリ（Dockerfileにて設定）。


<br>
###Volumes
ローカルのディレクトリをコンテナ内のディレクトリにマウントする。

```yml:
    volumes:
      - ./:/var/www
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
```

`- ホストのパス:コンテナ内の絶対パス`
コンテナ側は絶対パス。ホスト側は相対でも絶対でもいい。ボリューム名を定義指定いる場合は、ボリューム名でもいい。

`- ./:/var/www`
ローカルの現在のディレクトリをコンテナの「var/www」と同期させる。

これで、ローカルのプロジェクトディレクトリで行った変更はコンテナ内に自動コピーされる。

自動同期したくないディレクトリやファイルは、**.dockerignore**に記載する。


<br>
**▼ボリューム名について**
ボリューム名はserviceの外でvolumesを使って定義する。参照する際のボリューム名は**「プロジェクト名_ボリューム名」**となる。

ボリューム名を指定しない（ホストのパスを指定した）場合はハッシュ値となる。

```yml:docker-compose.ymlの例
#PJ名：laravel

version: '3'
services:
  #MySQL Service
  db:
    #省略
    volumes:
      - dbdata:/var/lib/mysql/
      - ./mysql/my.cnf:/etc/mysql/my.cnf
volumes:
  dbdata:
    driver: local
```

　↓

```:ボリューム名
$ docker volume ls
DRIVER    VOLUME NAME
local     laravel_dbdata
local     f0f9aa131ed1d74c0d2e9ff87b065170a1b142bd6a90a76ce9dcddbee3c69984
```


###networks
docker-composeはnetworkを指定しない場合、プロジェクト名のネットワークが自動生成され、すべてのサービスがそのネットワーク内に入る。

networkを自分で定義すると、指定したサービスだけをそのnetworkで繋ぐことができる。

```yml:
version: '3'
services:
  app:
    #省略
    networks:
      - app-network

    #省略

networks:
  app-network:
    driver: bridge
```

**▼ネットワークの確認**
ネットワーク名は指定の有無により名前が変わる

- 指定なし： `プロジェクト名_default`
- 指定あり： `プロジェクト名_ネットワーク名`

```:ネットワークの確認
$ docker network ls
NETWORK ID     NAME                         DRIVER    SCOPE
2cee68b9dc5a   django_default               bridge    local
761212ed4b49   laravel_app-network   bridge    
``` 

**▼bridgeとは？**
bridgeとはネットワークのブリッジモードのこと。複数のネットワークをつなげて、ひとまとめのネットワークにしている状態。



###links
サービスを関連づける。サービスを起動すると、linksで記述されているサービスも一緒に起動する。

```yml:
version: '3'
services:
  app:
    #省略
    links:
      - webserver
      - db
```

上記の場合、appにdbとwebserverがlinkしているため、appのみを起動すれば自動的にdbとwebserverも起動する。

起動の順序はlinksに記述したコンテナから。


```:起動例
$ docker-compose up -d app
Starting webserver ... done
Starting db        ... done
Starting app       ... done
```


<br>
以上で一つ目のphpサービスのdocker-composeの記述内容が完了。

処理をまとめると、
(1)イメージのビルド
Dockerfileを元に、php:7.4-fpmをベースイメージとして、必要なパッケージなどを保持した新たなイメージを作成。

(2)コンテナの起動
環境変数、ボリューム、ネットワーク、関連サービスを指定（リンク）してコンテナを起動。最後はDockerfileに記載されたCMDが実行され、イメージ通りのphp-fpmが起動する。



<br>
##2. Nginxのコンテナを作成
php-fpmのコンテナが作成できるようになったので、続いてWEBサーバーとなるNginxを作成する。


```yml:.yml
  #Nginx Service
  webserver:
    image: nginx:alpine
    container_name: webserver
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/var/www
      - ./nginx/conf.d/:/etc/nginx/conf.d/
    networks:
      - app-network
```

##2-1. イメージのビルド
イメージの作成は1行のみ。

```yml:
image: nginx:alpine
```

docker-hubの`nginx:alpine`をイメージとして使用。（alpine上に構築したnginx）

<br>
**▼alpineとは？**
alpineは超軽量のLinuxディストリビューション。

**▼Linuxディストリビューションとは？**
LinuxのコアとなるプログラムをLinuxカーネルという。この状態では普通のOSとして使うことが難しい。

使いやすいようにパッケージをくっつけたのがLinuxディストリビューション。distributionは配布という意味なので、配布用Linuxということ。

Debian, Ubuntu, CentOSと同じ並びにalpineがくる。


<br>
##2-2. コンテナの定義

```yml:
    container_name: webserver
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/var/www
      - ./nginx/conf.d/:/etc/nginx/conf.d/
    networks:
      - app-network
```

php-fpmサービスで使った内容とほぼ同じ。

作成したコンテナ名を**webserver**とし、コンテナ手動停止（&エラー）以外は自動再起動する。

コンテナのbashを起動できるように擬似ターミナル(tty)を開けておく。


###ports
`ホスト側：コンテナ側`でポート番号を指定する。

`- "80:80"`
であれば、localhost:80にアクセスすると、Nginxの80番ポートに繋がるという意味。

443ポートはhttpsプロトコル用のポート。
`https://xxx`で接続すると、xxxのIPアドレスの443ポートに接続する。


###volumes
・`- ./:/var/www`
ローカルの現在のディレクトリを、Dockerコンテナ内のNginxの/var/wwwと同期。


・`- ./nginx/conf.d/:/etc/nginx/conf.d/`
ローカルの./nginx/conf.d/をnginxの/etc/nginx/conf.d/と同期。


###networks
「project名_app-network」というネットワークに入ったサービス同士とつなげる。




<br>
##2-3. DBの定義

```yml:
  #MySQL Service
  db:
    image: mysql:5.7.22
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3307:3307"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: password
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - dbdata:/var/lib/mysql/
      - ./mysql/my.cnf:/etc/mysql/my.cnf
    networks:
      - app-network
```

設定はNignxサービスとほぼ同じ。
ベースイメージに、mysql:5.7.22を使用。
ポート番号はホスト側の3307をローカル側の3307につなげるよう設定。


###environment
環境変数でDB名やPWなどを渡している。


<br>
##2-4 networkとvolumeの定義
全体で使用するnetworkと、volume名をつけるものを定義している。。

```yml:
#Docker Networks
networks:
  app-network:
    driver: bridge
```

app-networkを定義。ドライバーはbridge（複数のネットワークを一つとみなす）


```yml:
#Volumes
volumes:
  dbdata:
    driver: local

```

名前ボリュームを設定する。名前ありボリュームを使うとデータを永続化できる。

ここでは、DBのデータはコンテナを終了しても残しておきたいので、dbdataボリュームを作成し、/var/lib/mysql/と連動させている。

コンテナ終了時にDocker内のデータは消えるが、ローカルにデータが残る。

Dockerではボリューム名dbdataでローカルのパスを保存してあるため、次のコンテナ起動時にそのローカルに接続し、/var/lib/mysql/配下にデータを保存する。（ローカルと同じ状態にする）



<br>
##まとめ
php-fpmは自分のLaravelプロジェクトを反映するためイメージの再構築をしているのでビルドに時間がかかる。

NginxとDB（MySQL）は公式のイメージを取得するのみなのでビルドもあっさり。（ただdocker-hubからプルするだけ）

コンテナ起動時にポート番号、環境変数、ボリューム、ネットワークを指定している。