設定ファイルを編集し docker-compose up を実行する(Django + MySQL④)

## この記事について
この記事は、**[Django + MySQLの環境構築を通じてDockerの使い方を学ぶ](https://qiita.com/toffe_hy/items/f17d78abd92f0b4272f6)**に関連する記事群の **Part.4** にあたります。

1. [venvを利用してPythonの仮想環境を構築する](https://qiita.com/toffe_hy/items/8c62f2bc7b14f1ce2ae0)
2. [Dockerfileの記述を考える](https://qiita.com/toffe_hy/private/0429a95bfe1786955c2a)
3. [docker-compose.ymlの記述を考える](https://qiita.com/toffe_hy/items/f2e6ecc516fdf593c777)
4. **設定ファイルを編集し docker-compose up を実行する ( 当記事 )**
5. [依存関係にあるサービス間のコンテナ起動タイミングを調整する](https://qiita.com/toffe_hy/items/4b7d8c47c5a1a2defcac)

## はじめに

この記事では、djangoプロジェクトの初期設定を行い、前回作成した`docker-compose.yml`を利用して開発サーバの実行を試みます。

## djangoの初期設定を行う

### ローカル用設定ファイルの作成

`settings.py`を編集する前に、`settings.py`と同じディレクトリに`local_settings.py`を作成します。
`GitHub`などに公開する場合は、このファイルを管理対象から外しておきます。

```python:config/local_settings.py
SECRET_KEY_LS = '**************************************************'
DB_NAME = "************"
DB_USER = "************"
DB_PASSWORD = "************"
```
`$ django-admin startproject`実行時に生成された`config/settings.py`の`SECRET KEY`を`SECRET_KEY_LS`として、こちらに記述を移します。
`DB_NAME`、`DB_USER`、`DB_PASSWORD`に関しては、前回作成した`.env`ファイルと同じ内容を記述して、MySQLコンテナのDBへDjangoを接続する際、以下ように`settings.py`からimportして利用します。

### 設定ファイルの編集
`settings.py`を編集します。

```python:config/settings.py
import os
import from .local_settings import SECRET_KEY_LS, DB_NAME, DB_USER, DB_PASSWORD

# (中略)

SECRET_KEY = SECRET_KEY_LS
```
まずは必要な変数等をimportして、`SECRET_KEY`に先ほどの`SECRET_KEY_LS`を代入します。

次に、同ファイル`ALLOWED_HOSTS`に`127.0.0.1`と`localhost`を追加します。

```python:config/settings.py
ALLOWED_HOSTS = ["127.0.0.1", "localhost"]
```
`"localhost"`はコンテナ内`~/etc/hosts`内の記述によって`"127.0.0.1"`に名前解決されるため内容としては同じものですが、使用感のためにここでは一応両方登録しておきます。

アプリケーションのサーバー自体は`docker-compose.yml`の`command`で指定した通り`0.0.0.0`で走らせますが、ここの記述を`localhost`に限定することによって、**ホストマシン以外からの接続を弾く**ようになっているはずです。(同じWiFi環境下の別端末から接続を試みる限りは、意図通りに設定できているようでした。)

最後に、DBの接続設定に関する項目を編集します。先ほど`local_settings.py`から必要なものは既にimportしてあるので、それぞれ当てはめていくだけです。

```python:config/settings.py
# Database

DATABASES = {
    'default': {
        'ENGINE': "django.db.backends.mysql",
        'NAME': DB_NAME,
        'USER': DB_USER,
        "PASSWORD": DB_PASSWORD,
        'HOST': "db",
        "PORT": "3306"
    }
}
```
`HOST`の部分は、`docker-compose.yml`で命名した**MySQL側のサービス名**を記入すればOKなので、ここでは`"db"`、ということになります。`PORT`は前回までの通りMySQLデフォルトの`3306`で指定しました。

これで基本的な設定は完了です。

## サーバーの実行

ここまでの設定で、**イメージとコンテナの立ち上げ、Djangoサーバーの実行**までが全て

```shell
$ docker-compose up
```
コマンド一発で行うことができるようになっているはずです。

しかし、実際に実行してみると、特定の条件下である問題が発生します。
これについては、次の記事
「[5. 依存関係にあるサービス間のコンテナ起動タイミングを調整する](https://qiita.com/toffe_hy/items/4b7d8c47c5a1a2defcac)」
をご参照ください。

## 動作確認について
サーバー実行時のログとしては、

```
djst_django | Starting development server at http://0.0.0.0:8000/
djst_django | Quit the server with CONTROL-C.
```
となりますが、設定の都合上、実際の動作確認は表示されている`http://0.0.0.0:8000/`ではなく、**`http://127.0.0.1:8000/`か`http://localhost:8000/`から行う**ことになります。

## ディレクトリ構成
```shell
django_starter
    ├── .venv
    │   └── (略)
    ├── config
    │     ├── __init__.py
    │     ├── asgi.py
    │     ├── local_settings.py    <- New!
    │     ├── settings.py
    │     ├── urls.py
    │     ├── wait_for_db.py       <- 別記事参照
    │     └── wsgi.py
    ├── mysql
    │     ├── data                 <- 自動生成
    │     │   └── (略)
    │     └── my.cnf
    ├── .env
    ├── docker-compose.yml
    ├── Dockerfile
    ├── manage.py
    └── requirements.txt
```

## コマンド各種
最後に、よく使うコマンドをこちらに書き留めておきます。

```shell
# $ pwd
# (略)/django_starter/

# django関連のコマンド ( shell, migrateなど )
$ docker-compose run web python manage.py [command]

# 開発サーバの実行
$ docker-compose up

# パッケージ更新
(.venv) $ pip install [ パッケージ名 ]
(.venv) $ pip freeze > requirements.txt

# コンテナに入る
$ docker-compose run --rm web /bin/bash # bashで入る
# もしくは...
$ docker-compose up -d # バックグラウンドで実行してから...
$ docker exec -it [ コンテナ名 ] /bin/bash # bashで入る

# コンテナの停止
$ docker-compose down
```

## 終わりに

以上で、この記事群での目的、**docker-composeを利用したDjango + MySQL環境の構築**は完了です。
この後自分好みにフロントエンド周りの設定を行なったものを、Djangoのテンプレートリポジトリとして管理し利用していこうと思っています。

取り組んでみた感想として、初学者の自分にとっては**Dockerだけでなくターミナル周りやネットワークについての基礎的な学習にもきっかけ**にもなり、やってみて学びが多いものになったと感じています。
とはいえ、依然ターミナルに流れるログを見ていると ( 特にMySQL関連については ) 改善しなければならなさそうな点が山ほど・・・。今後も学習を継続し、本番環境、例えばAmazon ECSでの利用など、より実戦に適した形で使いこなせる状態を目指していきたいと思っています。

ここまでご覧いただき、ありがとうございました。

.