この記事について
この記事は、Django + MySQLの環境構築を通じてDockerの使い方を学ぶに関連する記事群の Part.3 にあたります。
- venvを利用してPythonの仮想環境を構築する
- Dockerfileの記述を考える
- docker-compose.ymlの記述を考える ( 当記事 )
- 設定ファイルを編集し docker-compose up を実行する
- 依存関係にあるサービス間のコンテナ立ち上げタイミングを調整する
はじめに
この記事では、環境構築にあたっての手間や、実行が必要なコマンドを極力少なくしながら、今後できる限り狙った通りに Dockerコンテナ を作成することができるよう、**docker-compose.yml**の記述について考えていきます。
Dockerコンテナについては、前回までに学んだ Dockerイメージ を実際に動かし、その動かされた**「プロジェクト用の小さなマシン」の現在の状態を実体化したもの**と捉えています。
Djangoのコンテナは前回作成したDockerfileを元に、一方でMySQLのコンテナについては公式のイメージをそのまま使う流れで、作業を進めていきます。
今回は**docker-compose.ymlもDockerfileと同じ階層に作成**します。
記述内容
docker-compose.ymlの全体としての記述は、以下の通りです。
version: "3"
services:
web:
container_name: djst_django
build: .
restart: always
command: >
bash -c "
pip install -r requirements.txt &&
python manage.py runserver 0.0.0.0:8000
"
working_dir: /code
ports:
- 127.0.0.1:8000:8000
volumes:
- .:/code
depends_on:
- db
db:
container_name: djst_mysql
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: $DB_NAME
MYSQL_USER: $DB_USER
MYSQL_PASSWORD: $DB_PASSWORD
MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD
MYSQL_TCP_PORT: 3306
TZ: 'Asia/Tokyo'
volumes:
- ./mysql/data:/var/lib/mysql/
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
ports:
- 3306:3306
記述の意味を考える
version: "3"
1行目、docker-composeのファイルフォーマットのバージョンです。
$ docker-compose versionと実行して表示されるversionが1.13.0以降なら"3"、1.10.0以降なら"2"、このどちらでもなければ"1"になります。
services:
2行目から、このファイルで管理するサービス群に関する記述を始めます。
Django側
web:
3行目、Djangoのアプリケーションを動かすサービスに関する記述を始めます。ここでimage名 ( の末尾 ) が命名されます。
container_name: djst_django
4行目、生成されるコンテナの名前です。ここで命名します。
build: .
5行目、このdocker-compose.ymlから見たときに、どこにあるDockerfileを元にイメージを生成するかを指定します。今回は同階層に配置しているため、.と記述します。
6行目は後ほどMySQLの項目で考えます。
command: >
bash -c "
pip install -r requirements.txt &&
python manage.py runserver 0.0.0.0:8000
"
7-12行目、後ほど$ docker-compose upコマンドを実行した際に、コンテナ内から走らせたいコマンドを記述します。$ bash -c ""で、""内に記述したコマンドを実行してくれます。
pip installを実行しホストとコンテナ内で利用するパッケージ群を自動で同期Djangoサーバーの立ち上げをhost制限なし(0.0.0.0)で実行
これらを順番に実行するよう、&&で区切って記述しています。
hostの制限に関しては後ほどdjangoの設定ファイルから行います。
working_dir: /code
13行目、ワークディレクトリを指定します。コンテナ内のcodeディレクトリを指定します。このディレクトリは、前回記述したDockerfileの記述を元に作成されています。
ports:
- 127.0.0.1:8000:8000
14-15行目、利用するポートを指定します。左側127.0.0.1:8000がホストマシン側のhostとポート、:で挟んで右側がコンテナ側のポートに関する記述です。ホストマシン側から127.0.0.1:8000に接続すると、コンテナ側で自動で割り振られたhostの8000番に接続されます。指定するポートに関しては、先述のcommand内、runserverで指定するポートと一致させています。
(なお、今回の場合は後ほどlocalhostと127.0.0.1以外からの接続を弾くようDjango側から設定を行うため、127.0.0.1の記述は必須ではありません。)
volumes:
- .:/code
16-17行目、データのマウントについて指定します。前項と同じく**:を挟んだ左側がホストのパス、右側がコンテナ側のパス**です。変更が同期され、左右が同じ内容を管理する状態を保持します。この項目は他にもいろいろな記述の仕方がある ( 公式ドキュメント ) ようで、自在に使いこなすのは難しそうです。
depends_on:
- db
18-19行目、サービスの依存関係を指定します。webを起動する際に、先にdbも起動するということのようです。
起動順には問題が起こり得るのですが、とりあえずこれでDjangoアプリケーションのDBとしてMySQLを利用できるようになります。
MySQL側
続いて、MySQLのサービスに関する記述を考えていきます。
db:
20行目、MySQLの動かすサービスについての記述を開始します。先ほどと同様、これがイメージ名(の末尾)になります。
container_name: djst_mysql
21行目、コンテナ名を命名しています。
image: mysql:5.7
22行目、どのイメージを元に作成するかを指定しています。前述したwebの項目とは違い、Dockerfileでのカスタマイズを行わず、公式に準備されているイメージをそのまま利用する場合、このような記述になります。
もちろん、別のDockerfileをディレクトリを分けて作成しておけば、それを指定して利用することも可能です。
restart: always
23行目、コンテナ停止時の再起動に関する設定です。ここではalwaysに設定し、手動時をのぞき常に再起動させるようにしています。デフォルトは"no"で、alwaysの他にはunless-stoppedとon-failureが選択できるようです。
environment:
MYSQL_DATABASE: $DB_NAME
MYSQL_USER: $DB_USER
MYSQL_PASSWORD: $DB_PASSWORD
MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD
MYSQL_TCP_PORT: 3306
TZ: 'Asia/Tokyo'
24-30行目は、環境変数の設定です。$のついているものは、GitHubなどへ公開したくなった時のことも考え、後ほど作成する.envファイルに記述しておきます。これらが、Djangoから接続するDBの情報になります。
MYSQL_TCP_PORTは、後ほど見るportsオプションと整合性を持たせる必要があります。ここではMySQLのデフォルト番号3306を指定しました。TZは地域の設定です。
volumes:
- ./mysql/data:/var/lib/mysql/
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
31-33行目は、データのマウント設定です。これまでと同様、:より左がホストで、右がコンテナ内のパスです。
上行は、永続化のためのマウント設定です。アプリケーションが利用される過程でDBに保存された情報が、ホストの./mysql/dataディレクトリに同期されます。
下行は、設定ファイルのマウント設定です。言語設定などを記述した./mysql/my.cnfファイルを準備しておけば、コンテナ側のMySQLの設定に反映されます。
他にも、コンテナ内の/docker-entrypoint.init.dディレクトリ内にマウントする形でSQLファイルなどを用意しておけば、DBに初期データを投入することなどもできるようです。
ports:
- 3306:3306
最後に、利用するポートの設定です。先ほど記述した環境変数MYSQL_TCP_PORTと整合性を持たせればOKです。
.envファイルの作成
環境変数を記述するための**.envファイルを作成**します。こちらも同じ階層に配置します。
DB_NAME=********
DB_USER=********
DB_PASSWORD=********
DB_ROOT_PASSWORD=********
記述内容は、先ほどのdocker-compose.ymlで記述したenvironmentオプションに対応する環境変数の定義です。*********のところにお好みで記述してください。
GitHubなどに公開する場合は、このファイルは管理対象から外しておきます。
MySQL設定関連ファイルの作成
MySQLのマウント用ディレクトリ./mysqlを作成し、その中に設定ファイルmy.cnfを配置します。
[mysqld]
character-set-server=utf8mb4
[client]
default-character-set=utf8mb4
最初から変更しておきたい変数を予めこちらに記入しておきます。
DBのデータのマウント先に指定した./mysql/data/は、$ docker-compose up実行時に自動で生成されます。こちらはGitHubなどに公開する場合はあらかじめ管理対象から外しておきます。
現時点でのディレクトリ構成
django_starter
├── .venv
│ └── (略)
├── config
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── mysql <- New!
│ └── my.cnf
├── .env <- New!
├── docker-compose.yml <- New!
├── Dockerfile
├── manage.py
└── requirements.txt
終わりに
これで、Django+MySQL環境を構築するためのdocker-compose.ymlを作成することができました。
今回、それぞれのオプションの意味を理解しようと色々と調べてみて、Dockerについてはもちろん、MySQLやDjangoなどの**「扱いたい技術」そのものに対する知識を深めれば深めるほどもっと色々なことが自由にできそう**だと改めて感じたので、そちらも含めて引き続き学習を続けていきたいと思いました。
次回はDjangoの設定ファイルを編集し、$ docker-compose upコマンドを実行するまでを考えていきます。
次の記事はこちら↓
「 4. 設定ファイルを編集し docker-compose up を実行する 」
ご覧いただきありがとうございました。