はじめに
どうも、年末暇人の新人SEです。数ヶ月前に暇すぎてDjangoアプリケーションを勉強として作成したのですが、それを記事にするには題材がしょぼすぎると思ったのでDockerを使ってコンテナに乗っけて動かしてみました。作ったアプリケーションがしょぼいことは自覚してるので触れないでね!
環境
- Mac OS Catalina 10.15.1
- Docker 19.03.5
Djangoアプリケーションについて
まずはアプリケーションについて説明します。今回題材として使用するのは、以前僕が作成したサブスクリプションサービスの管理アプリケーションです。利用しているサービスと月額金額を登録するとその時点から現在までの累計課金額を計算できるようになっています。(できるのはそれだけです。。。)

どんだけゴミなのか見てみたいよ!という方は以下のリンクからご覧ください。README.mdとかは書いてないから頑張って動かして!笑
この記事ではすでに作成済みのDjangoアプリケーションをコンテナ環境に移植するということをやっていきます。
コンテナの構成
コンテナの構成は以下の通りです。AP用とDB用で2つのコンテナを作成します。
ディレクトリ構成
ディレクトリ構成は以下の通り。
.
├── Dockerfile_db
├── Dockerfile_django
├── README.md
├── app
│ ├── Pipfile
│ ├── Pipfile.lock
│ ├── env
│ │ ├── bin
│ │ ├── include
│ │ ├── lib
│ │ ├── pyvenv.cfg
│ │ └── src
│ ├── manage.py
│ ├── management
│ │ ├── __init__.py
│ │ ├── __init__.pyc
│ │ ├── __pycache__
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── apps.pyc
│ │ ├── forms.py
│ │ ├── migrations
│ │ ├── models.py
│ │ ├── models.pyc
│ │ ├── templates
│ │ ├── tests.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── static
│ │ ├── addService_style.css
│ │ ├── detail_style.css
│ │ ├── header_style.css
│ │ ├── login_style.css
│ │ ├── logout_style.css
│ │ ├── management_style.css
│ │ ├── password_change_done_style.css
│ │ ├── password_change_style.css
│ │ └── signup_style.css
│ ├── subscManagement
│ │ ├── __init__.py
│ │ ├── __init__.pyc
│ │ ├── __pycache__
│ │ ├── settings.py
│ │ ├── settings.pyc
│ │ ├── urls.py
│ │ └── wsgi.py
│ └── templates
│ └── registration
├── docker-compose.yml
└── requirements.txt
AP用コンテナのDockerfile
AP用コンテナを作成するためのDockerfileを作成します。
FROM python:3
ENV LANG en_US.utf8
WORKDIR /app
ADD requirements.txt /app
RUN apt-get update
RUN pip install -r requirements.txt
Django==2.2.5
mysqlclient==1.4.4
今回はMySQLへの接続ドライバとしてmysqlclientを使っていますが、後述のMySQLイメージのバージョン(Tag)がmysql:8だとうまくいきませんでした。今回はダウングレードしてmysql:5.7を使用しています。
DB用コンテナのDockerfile
DB用コンテナを作成するためのDockerfileを作成します。
FROM mysql:5.7
RUN apt-get clean && apt-get update && apt-get install -y locales locales-all
RUN locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:en
ENV LC_ALL ja_JP.UTF-8
RUN ln -sf /usr/share/zoneinfo/Japan /etc/localtime
文字コードの設定は適当です。
docker-compose.ymlの作成
docker-compose.ymlを作成します。
version: '3'
services:
db:
build:
context: .
dockerfile: Dockerfile_db
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: apuser
MYSQL_PASSWORD: password
MYSQL_DATABASE: subscManagement
TZ: "Asia/Tokyo"
BIND-ADDRESS: 0.0.0.0
ports:
- 3306:3306
volumes:
- db_data:/var/lib/mysql
tty: true
django:
build:
context: .
dockerfile: Dockerfile_django
command: python3 manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
volumes:
- ./app:/app
tty: true
depends_on:
- db
volumes:
db-data:
コンテナを削除してもDB内のデータが消えないようにvolumes:でボリュームを作成しています。
コンテナを実行
以下のコマンドでdocker-compose.ymlを基にコンテナを実行します。
$ docker-compose up --build -d
コンテナがしっかり動いているかを確認!
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------
subscmanagement_db_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
subscmanagement_django_1 python3 manage.py runserve ... Up 0.0.0.0:8000->8000/tcp
初回実行時のみDBへのテーブル作成のためにDjango側コンテナ内で以下のコマンドを実行する必要があります。
# "docker exec -it コンテナ名 /bin/bash"等でコンテナ内に入ってから実行
$ python manage.py migrate
Webページにアクセス
ブラウザからWebページにアクセスできるかどうか確認します。
http://0.0.0.0:8000/accounts/login/
にアクセス!

アクセスに成功しました!アカウントを作成してログインし、データを入力するとしっかり保存されたのでDBへの保存もうまくいっているようです!

ちなみに一度コンテナを削除してからもう一度作ってもデータは残っていたので、永続的なデータの保存にも成功しました!
最後に
今回初めてコンテナを触りましたがコンテナ間(Django側からMySQL側)の接続に苦労しました。DBへの接続ドライバとMySQLイメージのバージョン(Tag)の組み合わせによってはうまく接続することができないようです。これはMySQL:8から導入された新たな認証機能に接続ドライバが対応していない場合があるために起っているようです。コンテナ2つでも結構苦労したので、複雑なシステムのコンテナ化はかなり難しそう。。。