LoginSignup
1
1

More than 3 years have passed since last update.

docker-compose.ymlの記述を考える(Django + MySQL③)

Last updated at Posted at 2020-08-26

この記事について

この記事は、Django + MySQLの環境構築を通じてDockerの使い方を学ぶに関連する記事群の Part.3 にあたります。

  1. venvを利用してPythonの仮想環境を構築する
  2. Dockerfileの記述を考える
  3. docker-compose.ymlの記述を考える ( 当記事 )
  4. 設定ファイルを編集し docker-compose up を実行する
  5. 依存関係にあるサービス間のコンテナ立ち上げタイミングを調整する

はじめに

この記事では、環境構築にあたっての手間や、実行が必要なコマンドを極力少なくしながら、今後できる限り狙った通りに Dockerコンテナ を作成することができるよう、docker-compose.ymlの記述について考えていきます。

Dockerコンテナについては、前回までに学んだ Dockerイメージ を実際に動かし、その動かされた「プロジェクト用の小さなマシン」の現在の状態を実体化したものと捉えています。

Djangoのコンテナは前回作成したDockerfileを元に、一方でMySQLのコンテナについては公式のイメージをそのまま使う流れで、作業を進めていきます。

今回はdocker-compose.ymlDockerfileと同じ階層に作成します。

記述内容

docker-compose.ymlの全体としての記述は、以下の通りです。

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 ""で、""内に記述したコマンドを実行してくれます。

  1. pip installを実行しホストとコンテナ内で利用するパッケージ群を自動で同期
  2. 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に接続すると、コンテナ側で自動で割り振られたhost8000番に接続されます。指定するポートに関しては、先述のcommand内、runserverで指定するポートと一致させています。
(なお、今回の場合は後ほどlocalhost127.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-stoppedon-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ファイルを作成します。こちらも同じ階層に配置します。

.env
DB_NAME=********
DB_USER=********
DB_PASSWORD=********
DB_ROOT_PASSWORD=********

記述内容は、先ほどのdocker-compose.ymlで記述したenvironmentオプションに対応する環境変数の定義です。*********のところにお好みで記述してください。
GitHubなどに公開する場合は、このファイルは管理対象から外しておきます。

MySQL設定関連ファイルの作成

MySQLのマウント用ディレクトリ./mysqlを作成し、その中に設定ファイルmy.cnfを配置します。

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についてはもちろん、MySQLDjangoなどの「扱いたい技術」そのものに対する知識を深めれば深めるほどもっと色々なことが自由にできそうだと改めて感じたので、そちらも含めて引き続き学習を続けていきたいと思いました。

次回はDjangoの設定ファイルを編集し、$ docker-compose upコマンドを実行するまでを考えていきます。
次の記事はこちら↓
「 4. 設定ファイルを編集し docker-compose up を実行する

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

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1