【docker】LaravelからMySQLコンテナに接続するときのエラー対処法「php_network_getaddresses: getaddrinfo for example.com failed: Name or service not known」

Docker環境でLaravelからMySQLコンテナに接続する際に発生するエラーの考えられる原因と対処法です。
自分なりに調べた限りの内容なので不備があればご指摘いただけると幸いです。

# エラー内容
dockerでLEMP環境を構築し、Laravelからmysqlコンテナに接続した際に以下のようなエラーが発生。
```
php_network_getaddresses: getaddrinfo for example.com failed: Name or service not known
```

# 考えられる原因1: DBのホスト名が間違っている
よくある原因として、Laravelの.envファイルで設定しているDBのホスト名が間違っていることが挙げられます。
調べた限り、これが原因で接続エラーになる例が多かったです。
Laravelの.envファイルの中の「DB_HOST」は、デフォルトが「localhost (127.0.0.1)」になっているので見落としがちです。
Laravelから見たLocalhostはMySQLコンテナではないので変更する必要があります。
```
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT={ポート番号}
DB_DATABASE={データベース名}
DB_USERNAME={ユーザ名}
DB_PASSWORD={パスワード}
```

# DB_HOSTをコンテナ名に変更する
LaravelからDocker環境で同じネットワーク上のMySQLコンテナに接続する際は、.envファイルの「DB_HOST」をdocker-compose.ymlで設定したコンテナ名(container name)に設定すると、DBに接続できるようになります。

```powershell:.env
DB_CONNECTION=mysql
DB_HOST={コンテナ名} # ここをコンテナ名にする
DB_PORT={ポート番号}
DB_DATABASE={データベース名}
DB_USERNAME={ユーザ名}
DB_PASSWORD={パスワード}
```

```yml:docker-compose.yml
# mysqlコンテナ
  db:
    container_name: 'コンテナ名' # この名前を「DB_HOST」に設定する
    build:
      context: .
      dockerfile: ./docker/db/Dockerfile
    ports:
      - 3306:3306
    environment:
    (省略)
```
Docker環境において、LaravelからDB接続が上手くいかない際によくあるミスなので注意しておきたいです。
しかし、今回発生したエラーではこちらは正しく設定できていたので別の原因が考えられそうです。

# 考えられる原因2: ドメイン名の名前解決ができていない
もう１つ考えられる原因は、コンテナ内でドメイン名の名前解決ができていないことです。
ちなみに、今回発生したエラーの最終的な原因はこれでした。
エラー内容をもう一度読んでみると「example.com（接続したいドメイン名）への接続に失敗しました」的なことが書かれていました。(反省)

エラー内容
「php_network_getaddresses: getaddrinfo for example.com failed: Name or service not known」

今回のエラーが発生した背景として、まだ開発段階だったということもあり、使用したいドメイン名をDNSに登録していませんでした。
そのため、ひとまず公開前までは、Docker環境を構築したホスト側サーバーの「/etc/hosts」にドメイン名を登録して対処していました。
しかし、いざLaravelコンテナからMySQLコンテナに接続した際、Laravelコンテナ内の「/etc/hosts」ファイルにドメイン名を登録していなかったので、MySQLコンテナの接続の際にコンテナ内で名前解決ができていなかったようです。

# コンテナ内の「etc/hosts」にドメイン名を登録する
エラー原因がわかったので、Laravelコンテナ内に入って「etc/hosts」ファイルに使用したいドメイン名を登録します。
「/etc/hosts」ファイルは、IPアドレスとドメイン名の順番で書くことで設定できます。
```bash
# Laravelコンテナ内に入る
sudo docker compose exec (Laravelコンテナのサービス名) bash

# 「/etc/hosts」ファイルを編集
sudo vim /etc/hosts
```
```bash:/etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost6 localhost6.localdomain6

# 追記 (例)
192.168.x.x   example.com
```
これで今回のエラーが解消され、無事にMySQLコンテナに接続することができました。

ちなみに、docker-compose.ymlに「extra_hosts」を設定すると、コンテナ作成時に「etc/hosts」ファイルにドメイン名を登録することができる。
```yml:docker-compose.yml
  app:
    container_name: 'php-container'
    build:
      context: .
      dockerfile: ./docker/app/Dockerfile    
    extra_hosts:
      - example.com:192.168.x.x
      - example2.com:192.168.x.x
    (省略)
```
# まとめ
Docker環境でLaravelからMySQLコンテナに接続する際に、以下のエラーが出たときの対処法
「**php_network_getaddresses: getaddrinfo for example.com failed: Name or service not known**」

考えられる原因
1. DBのホスト名が間違っている
　→ Laravelの.envファイルの「DB_HOST」をdocker-compose.ymlで設定したコンテナ名に変更する
2. DNSにドメイン名を登録していない場合は、コンテナ内でドメイン名の名前解決ができていない
　→ Laravelコンテナに入って「/etc/hosts」ファイルに使用したいドメイン名を登録する


---
参考サイト
* [PHP Warning: php_network_getaddresses: getaddrinfo failed: Name or service not known in /some/path on line x](https://itecnote.com/tecnote/php-warning-php_network_getaddresses-getaddrinfo-failed-name-or-service-not-known-in-some-path-on-line-x/)
* [【Dockerエラー】php_network_getaddresses: getaddrinfo failed: Name or service not known](https://mykii.blog/php_network_getaddresses-getaddrinfo-failed-name-or-service-not-known/)
* [php_network_getaddresses: getaddrinfo failed: Name or service not known](https://stackoverflow.com/questions/2661546/php-network-getaddresses-getaddrinfo-failed-name-or-service-not-known)