はじめに
プログラミングスクールでRubyとRailsを学んだあと、個人的な関心からPythonとDjangoを触り始めたのですが、Djangoを扱い始めて最初に感じた個人的な印象は「(機能実装のための)コードを書き始めるまでの準備がそもそも、Railsと比べて難しい」というものでした。
今後、個人的に色々なアプリを作ったり、新しく学んだことを手を動かして実践したりする際の効率性を向上させるためには、その環境構築作業そのものに慣れることはもちろん、機能の実装や学習内容の実践に集中できるような体勢を整えることも必要だと感じ、コンテナ技術 ( の扱い ) について学んでみることにしました。
この記事 ( 群 ) の目的は、Django + MySQLの環境構築を通じて、Dockerの使い方の流れを学ぶこと、そして、自分用に使い回しのできるDjangoプロジェクトの雛形を作成することです。
1つ1つの記述の意味をなるべく丁寧に追っていくことによって、別言語/フレームワークを扱うときにも再現性のある知識の習得を目指していきたいと思っています。
Docker初心者による備忘録となりますが、よろしければお付き合いください。
実行環境
利用環境
- MacOS catalina 10.15.6
- Docker 19.03.8
(- docker-desktop for Mac 2.2.0.3)
- pyenv 1.2.20
構築を目指す環境
- Python 3.7.7
- Django 3.0.8
- MySQL 5.7.31
目次
-
venvを利用して仮想環境を準備する
venvを利用して、特定のバージョンのPython環境を準備します。Djangoプロジェクトの作成も行います。 -
Dockerfileの記述を考える
Dockerfileの記述を通して**Dockerイメージ
**について考えます。 -
docker-compose.ymlの記述を考える
docker-compose.ymlを作成し、Djangoとそれを接続するMySQLの設定を通して**Dockerコンテナ
**について学びます。 -
設定ファイルを編集し docker-compose up を実行する
Django
側の各種設定を行い、$ docker-compose up
を実行します。 -
依存関係にあるサービス間のコンテナ立ち上げタイミングを調整する
これまでの工程だと、特定の条件下でMySQLのコンテナがDjangoコンテナより先に立ち上がらず、接続に失敗することがあります。専用のPython
ファイルを作って問題の解決を目指します。 -
開発作業
あとは状況に応じて変更を加えつつ、開発作業に集中するだけです。
ソースコード
主な関連ファイルのソースコードを予めこちらにまとめておきます。
それぞれのファイルの記述内容については、前述した工程別記事にて説明します。
FROM python:3.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
COPY . /code/
EXPOSE 8000
version: "3"
services:
web:
container_name: djst_django
build: .
restart: always
command: >
bash -c "
pip install -r requirements.txt &&
python config/wait_for_db.py &&
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
import os
import MySQLdb
from time import sleep
from pathlib import Path
os.chdir(Path(__file__).parent)
from local_settings import DB_NAME, DB_USER, DB_PASSWORD
count_to_try = 0
LIMIT_OF_COUNT = 20 # 値は必要に応じて調整
def check_connection(count, limit):
"""
docker-compose up実行時用、時間調整のための関数。
"""
try:
conn = MySQLdb.connect(
unix_socket = "/var/run/mysqld/mysqld.sock",
user=DB_USER,
passwd=DB_PASSWORD,
host="db",
port=3306,
db=DB_NAME,
)
except MySQLdb._exceptions.OperationalError as e:
count += 1
print("Waiting for MySQL... (", count, "/ 20 )")
sleep(3)
if count < limit:
check_connection(count, limit)
else:
print(e)
print("Failed to connect mySQL.")
else:
print("Connected!\n")
conn.close()
exit()
if __name__ == "__main__":
check_connection(count_to_try, LIMIT_OF_COUNT)
ご指摘などありましたら、コメントいただけますと幸いです。
よろしくお願い致します。