djangoの仮装環境でDBが作成できない時の対処法

##### はじめに

みなさん、こんにちは。ゆうたです。

今回はタイトルにも記載した、djangoでDBが作成できない事象に遭遇したので記事にしたいと思います。
※初学者なので認識相違があればご指摘頂けますと幸いです。

##### 環境
```
Python 3.12.0
Django 5.0.6
```

##### 結論
コンテナにログインしてDB作成コマンドを実行すればdjangoのDBを作成をできる

##### やろうとしたこと
DBコンテナとWebコンテナを作成しdocker-compose upでコンテナを作成、起動してアプリを立ち上げたい。

##### 事象について
WebとDBコンテナは正常に立ち上がるものの、djangoの仮装環境からDBを作成するコマンドを実行しても以下のエラーが出力されてdjango内にDBが作成されませんでした。

実行コマンド
`(venv)%　python3 manage.py migrate`

エラーメッセージ
`Pdjango.db.utils.OperationalError: could not translate host name "db" to address: nodename nor servname provided, or not known`

##### 各種ファイル
```docker-compose.yml

version: "3.9"

services:
  db:
    image: postgres
    platform: linux/amd64
    volumes:
      - db-data:/var/lib/postgresql/data
    ports:
      - "5433:5432"
    environment:
      - POSTGRES_USER=XXXX
      - POSTGRES_DB=XXXX
      - POSTGRES_PASSWORD=XXXX
    healthcheck:
      test: "psql -U postgres"
      interval: 5s
      timeout: 5s
      retries: 5

  web:
    build: .
    command: python manage.py runserver 0.0.0.0:3000
    volumes:
      - .:/code
    ports:
      - "3000:3000"
    depends_on:
      db:
        condition: service_healthy

volumes:
  db-data:
  ```

```.env

DATABASE_URL="postgres://user:password@db:port/django_XXXX
SECRET_KEY='XXXX'
```

```settings.py

BASE_DIR = Path(__file__).resolve().parent.parent

env = environ.Env()
environ.Env.read_env(env_file=str(BASE_DIR) + "/.env") #.envファイルのPATHを指定　
〜省略〜
DATABASES = {
    "default": env.db(),#.envファイルに記載したDATABASE_URLを読み取りDBを作成する。
}
```

##### 調べてわかったこと
先述したエラーメッセージはsettings.pyとdocker-compose.ymlの情報が一致してないときに発生するエラーとのこと。
[参考サイト](https://blog.fantom.co.jp/2022/06/13/docker-django-migration-command-error/)

今回はsettings.pyから.envファイルに記載した環境変数を呼び出すようにしてるので.envファイルも確認していきます。

改めてエラーメッセージを確認すると「ホスト名をアドレスに変換できません」と言ってます。
`django.db.utils.OperationalError: could not translate host name "db" to address: nodename nor servname provided, or not known`

ホスト名はdocker-compose.ymlのservicesの名前とのことなので問題なさそう。
```docker-compose.yml

version: "3.9"

services:
  db: #←services:配下の部分がホスト名になる
```
[参考サイト](https://qiita.com/at-946/items/2fb75cec5355fad4050d#%E3%83%9B%E3%82%B9%E3%83%88%E5%90%8D%E3%81%8C%E9%81%95%E3%81%86)

.envファイルも@〜ポート番号の間がホスト名なので、dbになっていて問題なさそう。
```.env

DATABASE_URL="postgres://user:password@db:port/django_XXXX"
```
[参考サイト](https://qiita.com/UT_ITDaiku/items/0813cbf600e61ef4ed6b#database_url%E4%B8%80%E8%A6%A7)

docker-compose upコマンドを実行するとDBコンテナが問題なく起動してしまいどこがエラーの原因なのか掴めない。。

```
(venv) % docker-compose up                      
[+] Building 0.0s (0/0)                                                                                                                                                                    docker:desktop-linux
[+] Running 2/0
 ✔ Container django_ec-db-1   Created                                                                                                                                                                      0.0s 
 ✔ Container django_ec-web-1  Created                                                                                                                                                                      0.0s 
Attaching to django_ec-db-1, django_ec-web-1
django_ec-db-1   | 
django_ec-db-1   | PostgreSQL Database directory appears to contain a database; Skipping initialization
django_ec-db-1   | 
django_ec-db-1   | 2024-05-22 07:57:59.865 UTC [1] LOG:  starting PostgreSQL 16.3 (Debian 16.3-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
django_ec-db-1   | 2024-05-22 07:57:59.866 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
django_ec-db-1   | 2024-05-22 07:57:59.866 UTC [1] LOG:  listening on IPv6 address "::", port 5432
django_ec-db-1   | 2024-05-22 07:57:59.874 UTC [29] LOG:  database system was shut down at 2024-05-22 01:55:54 UTC
django_ec-db-1   | 2024-05-22 07:57:59.881 UTC [1] LOG:  database system is ready to accept connections #←django内にDBは作られていないものの、DBコンテナは起動している
django_ec-web-1  | Watching for file changes with StatReloader
django_ec-web-1  | Performing system checks...
django_ec-web-1  | 
django_ec-web-1  | System check identified no issues (0 silenced).
〜〜省略〜〜
django_ec-web-1  | Starting development server at http://0.0.0.0:3000/
django_ec-web-1  | Quit the server with CONTROL-C.
django_ec-web-1  | 
```

##### 解消したやり方
プログラミングスクールの講師に相談し、WebコンテナにログインしてDBを作成するコマンドを打ったらdjango内にDBが作成された。。。！

1.コンテナにログイン
`docker-compose exec <コンテナ名> sh`

2.django内部でDBを作成するコマンドを実行
`python3 manage.py migrate`

3.DBが正常に作成された！
```
Operations to perform:
  Apply all migrations: admin, auth, contenttypes
Running migrations:
  Applying contenttypes.0001_initial... OK
  ~省略~
  Applying 0001_initial... OK
  Applying sessions.0001_initial... OK
```

##### 事象の原因について
こちらの記事には「ホスト名が異なっている場合のエラー」と記載があったのですが、結局のところ詳しい原因については特定できませんでした。
もし、今後学習を進めていくうえで分かったことがあれば、適宜追記していくようにしたいと思います。

##### まとめ
コンテナが問題なく作成、起動するのにdjangoの仮装環境からDBを作成できない場合は、一度コンテナにログインしてからDBを作成するとうまくいく可能性がある。