64
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Django+MySQLの開発環境をdocker-composeで構築する

Last updated at Posted at 2020-08-21

はじめに

既に書き尽くされたような記事のタイトルですが、 自分がわかりやすいように 書いた備忘録です。
独学でやってて詰まったポイントや設定ファイルの記述内容など、コメントを付けつつ書いていきます。
Djangoチュートリアルのpollsアプリをマイグレートするところまでやります。

注意:結構長いです
最終的なソースコードはこちら(github)

環境

  • OS: Mac
  • Docker Desktop
    • Docker version 19.03.12
    • docker-compose version 1.26.2

エディタはVSCodeで、Docker拡張機能を使用しています。
コンテナへのログインや、コンテナ再起動などGUIで操作できて便利です。

開発環境を構築する

webサービス(Django)とdbサービス(MySQL)のコンテナを立てていきます。

1.作業ディレクトリ作成

最初はターミナルで操作します。

docker-compose.ymlファイルが置いてあるディレクトリ名が、コンテナ名やボリューム名の接頭辞になります。
コンテナ名が既にあるものだとうまく立ち上がらないため、他で使ってないプロジェクト名などにします。

bash
$ mkdir sample-pj
$ cd sample-pj/       # 作業ディレクトリに移動

ファイルの配置

作った作業ディレクトリの中に、Dockerfile、docker-compose.yml、requirements.txtを配置します。

bash
$ touch Dockerfile docker-compose.yml requirements.txt

Dockerfile編集

ここからはVSCodeで操作していきます。
[cmd + shift + m] -> [ターミナルタブ]でターミナル操作も一緒にできます。

webサービス(Django)用のdockerイメージを作成するためのコマンドを書いていきます。
Docker Hubで提供されているpython:3実行環境のイメージに、いろいろ付け加えた新しいイメージを作ります。

Dockerfile
FROM python:3            # 元となるdockerイメージを指定
ENV PYTHONUNBUFFERED 1   # この環境変数に値を入れることでバッファを無効化する('1'じゃなくてもいい)
RUN mkdir /code          # codeディレクトリを作成
WORKDIR /code            # codeディレクトリに移動
COPY requirements.txt /code/   # txtファイルをcodeディレクトリに配置
RUN pip install --upgrade pip && pip install -r requirements.txt
          # pipコマンドを最新にし、txtファイル内のパッケージ(後述)をpipインストール
COPY . /code/            # sample-pj/配下のファイルをcodeディレクトリにコピー

requirements.txt編集

webサービスにインストールするパッケージを指定

requirements.txt
Django==3.1   # Django3.1
mysqlclient   # pythonでMySQLに接続するためのドライバ

docker-compose.yml編集

コンテナ作成の命令

docker-compose.yml
version: '3'       # 1
services:          # 2
  db:
    image: mysql:5.7    # 3
    environment:                  # 4
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: django-db
      MYSQL_USER: django
      MYSQL_PASSWORD: django
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
                                  # 5
  web:
    build: .       # 6
    command: python3 manage.py runserver 0.0.0.0:8000 # 7
    volumes:                  # 8
      - .:/code
    ports:                    # 9
      - "8000:8000"
    depends_on:               # 10
      - db

10箇所、解説します。

  1. version: '3'
    • docker-compose.ymlのファイル形式のバージョンを指定します
  2. services
    • dbサービスとwebサービス、2つのコンテナが起動します
    • サービス名は好きな名前で大丈夫です。[docker-compose.ymlがあるディレクトリの名前]_[サービス名]という名前のコンテナが立ち上がります
  3. image: mysql:5.7
  4. environment
    • MYSQL_ROOT_PASSWORD: root
      • ルートユーザのパスワードを設定します
      • ルートユーザ自体は自動で作成されているようです
    • MYSQL_DATABASE: django-db
      • Djangoのプロジェクトで使うDBの名前を設定します
    • MYSQL_USER: django
      • Djangoのプロジェクトから接続する際のユーザ名を設定します
    • MYSQL_PASSWORD: django
      • 上で設定したユーザのパスワードを設定します
    • TZ: 'Asia/Tokyo'
      • dbサーバのタイムゾーンを設定します
  5. command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
  6. build: .
    • Dockerfileをもとにイメージをビルドします
    • .はDockerfileがある場所です
  7. command: python3 manage.py runserver 0.0.0.0:8000
    • コンテナ起動時に(引数にコマンドを指定しなかったときだけ)実行されるコマンドです
    • Djangoの軽量サーバーを、ポート指定して立ち上げます
  8. volumes
    • .:/code
    • カレントディレクトリを/codeにバインドマウントします
  9. ports
    • "8000:8000"
    • 左は公開用のポート、右は転送先コンテナのポート
    • 転送先ポートは、7で指定したDjangoサーバーのポートに合わせる必要があります
  10. depends_on:
    • 先にdbサービスを起動してからwebサービスを起動するように設定します

これで、2つのコンテナを立ち上げるための準備が完了しました。

Djangoのプロジェクトを作成

webサービスのコンテナを起動し、Djangoのプロジェクト作成コマンドを実行

bash
docker-compose run web django-admin.py startproject djangopj .
  • docker-compose run web
    • webサービスだけを指定します
  • django-admin.py startproject djangopj .
    • djangopjという名前のプロジェクトを作成します
    • このカレントディレクトリは、Dockerfileで指定した/codeです

コマンドを実行すると、プロジェクトディレクトリとmanage.pyが作られています。
コンテナの/codeディレクトリと、現在のカレントディレクトリがバインドマウントされているためです。

bash
$ ls
Dockerfile         docker-compose.yml requirements.txt
djangopj           manage.py

DBの設定を編集

djangopj/settings.pyを開き、DATABASESの項目を編集します。

settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django-db',
        'USER': 'django',
        'PASSWORD': 'django',
        'HOST': 'db',
        'PORT': '3306'
    }
}

NAME、USER、PASSWORDにはdocker-compose.ymlで設定したものを記載します。
HOSTにはサービス名を記載します。

各サービスを起動

bash
$ docker-compose up -d

-dオプションはデタッチドモードです。
後ろでコンテナが動き続けます。

http://localhost:8000 にアクセスすると、Djangoのトップページが表示されると思います。
image.png

表示されない場合、コンテナの実行ログを確認してみましょう。
VSCodeのDocker拡張機能を入れている場合、左のDockerタブから簡単にログにアクセスできます。

確認したいコンテナの上で右クリック -> View Logs
image.png

dbサービスの起動完了が遅く、webサービスの起動がこけることがあるので
webサービス右クリックで Restart をかけると解決します。

アクセスできたら、MySQL側にDjango用のDBが作られているかどうかも確認してみましょう。

同じようにdbサービスのコンテナの上で右クリックし、
Attach Shell をクリックします。

すると、ターミナル画面でdbサービスに入った状態になるので、
mysqlにログインします。

mysql
# mysql -u root -proot

DB一覧を表示させると、、

mysql
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| django-db          |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

無事、django-dbが作成されていました!

pollsアプリでデータ連携の確認

webサービスとdbサービスが連携できているか確認するために、
Djangoの公式チュートリアルを参考に小さなアプリを作ります。
https://docs.djangoproject.com/ja/3.1/intro/tutorial01/#creating-the-polls-app

アプリケーションをつくる

docker-compose.ymlのあるディレクトリ(sample-pj)に移動し、以下コマンドを叩きます。

bash
$ docker-compose run web python3 manage.py startapp polls

lsして、pollsというディレクトリができていれば作成完了です。

モデルを作る

pollsディレクトリにあるmodels.pyを編集

models.py
from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

djangopj/settings.pyのINSTALLED_APPSにpollsアプリケーションを追加します。

settings.py
INSTALLED_APPS = [
    'polls.apps.PollsConfig',     # 追加
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

モデルをDBに適用

docker-compose.ymlのあるディレクトリ(sample-pj)に戻り、以下コマンドを叩きます。

bash
$ docker-compose run web python3 manage.py makemigrations polls
$ docker-compose run web python3 manage.py migrate

これでDBにモデルが適用されました。MySQL側で確認してみます。

mysql
mysql> use django-db;
mysql> show tables;
+----------------------------+
| Tables_in_django-db        |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
| polls_choice               |
| polls_question             |
+----------------------------+
12 rows in set (0.00 sec)

polls_choice、polls_questionテーブルが作成されました。

こちらを参考に、管理画面からデータを入れてみると、
テーブルの中身にデータが登録されているのも確認できます。

mysql
mysql> select * from polls_question;
+----+---------------+----------------------------+
| id | question_text | pub_date                   |
+----+---------------+----------------------------+
|  1 | test          | 2020-08-21 08:58:07.000000 |
+----+---------------+----------------------------+
1 row in set (0.00 sec)

これで、webサービスとdbサービスでデータのやりとりができていることが確認できました。

あとがき

docker-compose.ymlの記述内容と、settings.pyのDATABASESの書き方が謎で
ずっとモヤモヤしていたのが、最近やっとすっきりしたので記事にしてみました。

個人的には、webコンテナをリスタートしないといけないのがイケてないので
改善の余地ありかなと思います。

VSCode拡張機能の良さが伝わってたら幸いです。

64
70
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
64
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?