Docker ComposeでDjangoの開発環境を構築した
これまで一つのコンテナにMySQLやWordPressをまとめて突っ込んで動かしていたのですが、そのような素人的な使い方を脱出しようと思い、Docker Composeの使い方を学ぶことにしました。
Docker Composeは複数のコンテナをポコポコ立ててくれるツールです。
Dockerはデータベース、サーバー、バックエンド、フロントなど、役割ごとにコンテナを用意してアプリ構築することを推奨していますが、それぞれのコンテナを一つずつ用意していくの面倒ですよね。そこでDocker Compose。これを使うことで一度に複数のコンテナを積み上げて、瞬時に環境を構築することができます。
今回は練習がてら、Djangoの開発環境を作ってみます。
はじめに
DockerとDocker Composeが必要なので、インストールします。
コンポーネントの定義
次のようにDBとWebのコンテナで構成します。
- Web…Pythonのイメージから起動したDjangoのコンテナ
- DB…PostgreSQLのコンテナ
必要なファイルとディレクトリは下記の通り。
.
├── Dockerfile
├── docker-compose.yml
└── requirements.txt
Dockerfileの準備
PythonのイメージにDjangoを突っ込むため、Dockerfileを準備します。
FROM python:3.7
ENV PYTHONUNBUFFERED 1
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
FROM python:3.7
version3.7のPythonが格納されたイメージを指定しています。
ENV PYTHONUNBUFFERED 1
コンソールのstdout(標準出力)とstderr(標準エラー出力)のバッファーを無効にする設定です。
例えば次のようなコマンド。数字の 10 が出力された後、5秒待った後に数字の100が出力される単純なコマンドですが、 cat
コマンドをパイプに通しています。
python -c 'import time; print(10); time.sleep(5); print(100)' | cat
バッファーが有効な場合、5秒後のタイミングで数字の10と100が同時に出力され、本来意図したものと異なる出力になります。 PYTHONUNBUFFERED でバッファーを無効にすることで、このような挙動を抑止することができます。
ADD requirements.txt /code/
`WORKDIR /code` `ADD requirements.txt /code/` `RUN pip install -r requirements.txt`
これはDockerfileと同じディレクトリに用意したrequirements.txtをイメージの /code ディレクトリに配置し、必要なツールのインストールを行います。
requirements.txtの準備
PythonのイメージにDjangoとPostgreSQLのライブラリをインストールするために使います。
Django==2.1.1
psycopg2
psycopg2-binary
docker-compose.ymlの準備
Docker Composeの要となるymlファイルです。どのようなコンテナのアプリ構成にするのかをこのファイルで設定します。
version: "3"
services:
db:
image: postgres:10
web:
build: .
volumes:
- .:/code
tty: true
ports:
- 8000:8000
depends_on:
- db
version: “3”
ymlのファイル形式を指定しています。
services:
このハッシュの配下にコンテナの情報をまとめていきます。
db:
データベース用のコンテナを設定しています。
web:
Djangoアプリ用のコンテナを設定しています。
build: . は docker-compose.yml が置かれているディレクトリのDockerfileを指定してイメージをビルドしてくれます。
volumes:、 docker-compose.yml が置かれているディレクトリをコンテナの /code へマウントします。
tty: true、コンテナを起動したままにするオプション。シェルを実行するようなコンテナを使う場合に必要。
ports:、ホストの8000番からコンテナの8000番へポートフォワード。
depends_on: これを指定すると、指定したコンテナの起動を待ってから対象のコンテナを起動します。
サービスの起動
docker-compose.ymlが置かれているディレクトリへ移動し、次のコマンドを実行します。
docker-compose up -d
-dオプションでデタッチモードでコンテナ群を起動させます。アクセスログの内容やエラーなどを確認したい場合は、-dを外して実行します。
実行するといい感じにコンテナが二つ動いているはず。
docker container ls
# docker container lsコマンドの出力結果の例
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1a4665029e96 django-dev_web "python3" 9 seconds ago Up 7 seconds 0.0.0.0:8000->8000/tcp django-dev_web_1
350f65de1ef2 postgres:10 "docker-entrypoint.s…" 10 seconds ago Up 9 seconds 5432/tcp django-dev_db_1
Djangoプロジェクトの作成
起動したWebコンテナで django-admin startproject コマンドを実行します。
docker container exec -it {CONTAINER_NAME} django-admin startproject {PROJECT_NAME}
例: docker container exec -it django-dev_web_1 django-admin startproject test
成功すると、指定したプロジェクトが作成されます。
.
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── test # <--PROJECT_NAME
├── manage.py
└── test
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
Djangoプロジェクトの環境変数の設定
作成されたプロジェクト配下にある settings.py を開き、 DATABASES 関数を書き換えます。必要に応じて ALLOWED_HOSTS の値も修正します。
DATABASESの設定
DATABASESを次のように書き換えて、PostgreSQLのコンテナと通信できるようにします。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'HOST': 'db',
'PORT': 5432,
}
}
ここで大事なのが、 HOST で指定している db という値。これはdocker-compose.ymlで設定したPostgreSQLのサービス名と同じにする必要があります。通常、 HOST にはホスト名だったりIPアドレスを入れるのですが、docker-compose.ymlの設定にしたがって、いい感じに名前解決してくれます。
ALLOWED_HOSTSの設定
これは環境によるのですが、Dockerを動かしているホストの名前、IPアドレスを入力します。例えば↓このような感じです。
ALLOWED_HOSTS = ['localhost', '192.168.33.15', '[::1]']
開発環境と割り切って使うのであれば、次のように全て許可してもいいでしょう。
ALLOWED_HOSTS = ['*']
Djangoプロジェクトの起動
これで準備が整いました。Djangoのサーバーを起動し、ブラウザからアクセスします。
docker container exec -it {CONTAINER_NAME} python {PROJECT_NAME}/manage.py runserver 0.0.0.0:8000
例: docker container exec -it django-dev_web_1 python test/manage.py runserver 0.0.0.0:8000
ブラウザへのアクセス例: http://192.168.33.15:8000
まとめ
Docker Composeを使ってDjangoの開発環境を作りました。これでDjangoをいじり放題です。やったね!