docker-composeでWebアプリケーションをデプロイする
djangoで作成したWebアプリケーションをLinuxマシンにデプロイしてみたのでやったことを書き記します。
システム構成
このようなシステム構成でdockerコンテナを構成します。
WebServerとAPServerのdockerコンテナを作り、それらのコンテナをdocker-composeでまとめてビルド・実行します。WebServerとしてはNGiNXを使い、静的コンテンツはVolumeから配信します。動的コンテンツはAPServerにリクエストを送信し、APServerがレスポンスを生成します。
APServerの負荷軽減のため、静的コンテンツと動的コンテンツの配信責務を分担する構成としています。静的コンテンツはコンテナをビルドする際に共有しているVolumeに配置します。
各ソフトウェアについて軽く説明します。
NGiNX
Webサーバ。リバースプロキシ、ロードバランサ、HTTPキャッシュなどの機能を持つ。性能面に焦点をあてて開発がされています。
NGiNX → Gunicorn(http)
リクエストに応じて、動的コンテンツはアプリケーションサーバへルーティングする。
Gunicorn
グリーンユニコーン。PythonのWSGI HTTPサーバ。Python のAPサーバとしては、他にもuWSGIやNGiNX Unit等があるらしい。
WSGI
Web Server Gateway Interfaceの略。Pythonにおいて、WebサーバとWebアプリケーションを接続するための標準化されたインタフェース定義。ういすきー(whisky?)と発音するらしい。
Django
ジャンゴ。Pythonで実装されたWebアプリケーションフレームワーク。MVCライクなMTVモデルのフレームワークを提供する。Flaskがマイクロフレームワークに対して、Djangoはフルスタックフレームワークとなっている。
Python
ぱいそん。プログラミング言語。ここではPythonで書かれたアプリケーションを指す。
docker-compose構成
このようなファイル構成で実現します。
docker-compose
├─<django-project> #このディレクトリ以下の構成は省略
├─nginx
│ ├─default.conf
│ └─Dockerfile
├─.env
├─docker-compose.yml
├─Dockerfile
├─entrypoint.sh
└─requirements.txt
上から順に中身を書いていきます。
upstream django {
server gunicorn_django:8000;
}
server {
listen 80;
location / {
proxy_pass http://django;
}
location /static/ {
alias /static/;
}
}
FROM nginx:1.19.0-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
SECRET_KEY=<settings.pyのSECRET_KEY>
DEBUG=False
HTTP_PROXY=<user>:<pass>@<proxyserver>:<port>
NO_PROXY=*.*.*.* #プロキシ通したくないドメインやIPを設定する
企業内等でプロキシサーバの設定が必要な場合は環境変数として設定しておく。プロキシ設定しておかないとコンテナビルド時のpip install等ができなくなります。企業内でなければ設定しなくてもいいかと思います。
version: '3.8'
services:
gunicorn_django:
environment:
- HTTP_PROXY=$HTTP_PROXY
- http_proxy=$HTTP_PROXY
- HTTPS_PROXY=$HTTP_PROXY
- https_proxy=$HTTP_PROXY
- FTP_PROXY=$HTTP_PROXY
- ftp_proxy=$HTTP_PROXY
- NO_PROXY=$NO_PROXY
- no_proxy=$NO_PROXY
volumes:
- static:/static
env_file:
- .env
build:
context: .
args:
- HTTP_PROXY=$HTTP_PROXY
- http_proxy=$HTTP_PROXY
- HTTPS_PROXY=$HTTP_PROXY
- https_proxy=$HTTP_PROXY
- FTP_PROXY=$HTTP_PROXY
- ftp_proxy=$HTTP_PROXY
- NO_PROXY=$NO_PROXY
- no_proxy=$NO_PROXY
ports:
- "8000:8000"
nginx:
build:
context: ./nginx
args:
- HTTP_PROXY=$HTTP_PROXY
- http_proxy=$HTTP_PROXY
- HTTPS_PROXY=$HTTP_PROXY
- https_proxy=$HTTP_PROXY
- FTP_PROXY=$HTTP_PROXY
- ftp_proxy=$HTTP_PROXY
- NO_PROXY=$NO_PROXY
- no_proxy=$NO_PROXY
volumes:
- static:/static
ports:
- "80:80"
depends_on:
- gunicorn_django
volumes:
static:
FROM python:3.9-alpine
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY ./<django-project> /app
WORKDIR /app
COPY ./entrypoint.sh /
ENTRYPOINT ["sh", "/entrypoint.sh"]
#!/bin/sh
python manage.py migrate --no-input
python manage.py collectstatic --no-input
gunicorn <appname>.wsgi:application --bind 0.0.0.0:8000
<appname>には<django-project>内のアプリケーション名を記述します。migrateとcollectstaticのオプションに–no-inputをつけておかないとアプリケーションをアップデートして再ビルドした時にユーザ入力待ちになってしまいタイムアウトでビルドが失敗します。
Django==3.1.5
gunicorn==20.0.4
requirements.txtには他にもpip installする必要があるパッケージを記述します。
いざ、デプロイ
ここまで設定ができたらコンテナをビルドして実行します。バックグラウンドで実行する場合は-dのデタッチオプションをつけてください。
$ docker-compose up --build
アプリケーションを更新するときはCtrl+Cで止めるか、docker-compose downして止めます。コンテナがdownしているのを確認して、アプリケーション更新(git pull等)して再度上記のビルドコマンドを叩けば更新できます。
ディスカッション
コメント一覧
まだ、コメントがありません