DjangoをNGINX/Unitで公開するためのDockerコンテナを作成します。
内容
-
前記事で
Windows10+WSL+Docker
環境を構築 - NGINX/Unit+Djangoのコンテナを構築
カスタマイズ
NGINX/Unitとは?
公式サイトに記載の通り、(誤解を恐れず表現すると)NGINXの動的アプリサーバ版です。
WSGIに沿ってPythonスクリプトを記述することで、動的アプリを公開できます。
- WSGIに準拠したスクリプトを直接起動できる (中間モジュールを必要としない)
- 設定更新を動的に実施できる(ソケットに流し込む)
Djangoとは?
DjangoはPythonの代表的フルスタックフレームワークです。
用意するもの
名称 | 内容 | |
---|---|---|
Docker | Dokerfile | Dockerイメージのレシピ |
unit.conf.json | NGINX Unitの設定 | |
entrypoint.sh | コンテナ起動スクリプト | |
requirements.pip |
pip freeze の出力 |
|
.docerignore | 参考サイト | |
コンテンツ | Pythonスクリプト | Djangoで作成 |
src/
├── Dockerfile
├── .dockerignore
├── unit.conf.json
├── entrypoint.sh
├── requirements.pip
└── xxx/ (Django)
├── xxx
| ├── wsgi.py
| └── etc...
└── polls
※DjangoははじめてのDjangoあたりを参考に学習してください。
※ディレクトリツリーキレイに書きたい
Dokerfile
公式イメージのDockerfileを参考にしつつ作成します。
公式はDebianでPythonバージョンも古いため、UbuntuイメージにNGINX/Unitを導入する形にします。
ENVにユーザーとパスワードを記述している点が気になる方は、適宜ARGに置き換えてください。
FROM ubuntu:cosmic
ENV UBUNTU_VER cosmic
ENV PY_VER 3.6
SHELL ["/bin/bash", "-c"]
ENV DEBCONF_NOWARNINGS yes
LABEL MAINTAINER="auther"
LABEL version="1.0"
LABEL description=""
ENV CONTENTS ./project
ENV EXPOSE_PORT 8000
ENV USER api
ENV PASSWORD pass
ENV HOME /home/${USER}
ENV PROJECT_NAME xxx
ENV PROJECT_DIR ${HOME}/${PROJECT_NAME}
# initialize
RUN : "locale setting and base package" && \
set -o pipefail && \
perl -p -i.bak -e 's%https?://(?!security)[^ \t]+%http://ubuntutym.u-toyama.ac.jp/ubuntu/%g' /etc/apt/sources.list && \
apt-get -y clean && apt-get -y update && \
apt-get -qy install \
sudo \
tzdata \
ca-certificates \
gnupg \
curl && \
update-locale LANG=ja_JP.UTF-8 && \
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
: "create user" && \
useradd -m -s /bin/bash ${USER} && \
gpasswd -a ${USER} sudo && \
echo "${USER}:${PASSWORD}" | chpasswd && \
echo "Defaults visiblepw" >> /etc/sudoers && \
echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# copy project
WORKDIR ${HOME}
COPY ${CONTENTS} ${HOME}/${PROJECT_NAME}
COPY unit.conf.json ${HOME}
COPY entrypoint.sh ${HOME}
COPY requirements.pip ${HOME}
RUN set -o pipefail && \
sed \
-e "s#%%HOME%%#$HOME#g" \
-e "s#%%PJ%%#$PROJECT_NAME#g" \
-e "s#%%PORT%%#$EXPOSE_PORT#g" \
-e "s#%%PYVER%%#$PY_VER#g" \
${HOME}/unit.conf.json > ${HOME}/unit-conf.json && \
chown -R ${USER}:${USER} ${PROJECT_DIR} && \
chown ${USER}:${USER} ${HOME}/unit.conf.json && \
chown ${USER}:${USER} ${HOME}/entrypoint.sh && \
chown ${USER}:${USER} ${HOME}/requirements.pip && \
ln -sf /dev/stdout ${HOME}/unit.log && \
chmod 774 ${HOME}/entrypoint.sh
# install Project Package
WORKDIR /root
RUN set -o pipefail && \
: "nginx unit repogitory" && \
curl -fsSL "https://nginx.org/keys/nginx_signing.key" | apt-key add - && \
echo "deb https://packages.nginx.org/unit/ubuntu/ ${UBUNTU_VER} unit" > /root/unit.list && \
echo "deb-src https://packages.nginx.org/unit/ubuntu/ ${UBUNTU_VER} unit" >> /root/unit.list && \
cp /root/unit.list /etc/apt/sources.list.d/unit.list && \
: "project packages" && \
apt-get -y update && apt-get -qy install \
unit \
unit-python${PY_VER} \
python3 \
python3-pip
# pip
USER ${USER}
WORKDIR ${HOME}
RUN pip3 install -r ${HOME}/requirements.pip
# start unitd
STOPSIGNAL SIGTERM
EXPOSE ${EXPOSE_PORT}
CMD ["sh", "./entrypoint.sh"]
unit.conf.json
公式ドキュメントを参考にNGINX/Unitの設定を記述したjson形式のファイルを用意します。
"%%"で囲んでいる箇所はdockerfile内で置換しています。
{
"listeners": {
"*:%%PORT%%": {
"application": "%%PJ%%"
}
},
"applications": {
"%%PJ%%": {
"type": "python %%PYVER%%",
"processes": 5,
"working_directory": "%%HOME%%/%%PJ%%/",
"path": "%%HOME%%/%%PJ%%/",
"module": "%%PJ%%.wsgi",
"user": "api",
"group": "api",
"limits": {
"timeout": 10,
"requests": 1000
}
}
},
"settings": {
"http": {
"header_read_timeout": 10,
"body_read_timeout": 10,
"send_timeout": 10,
"idle_timeout": 120,
"max_body_size": 6291456
}
},
"access_log": "%%HOME%%/access.log"
}
entrypoint.sh
コンテナ生成後に実行するシェルスクリプトです。Dockerfile末尾で実行しています。
NGINX Unitを実行する方法は他にもありますが、今回はシンプルに実行します。
#!/bin/sh
sudo unitd --control unix:./control.unit.sock --log ./unit.log
sudo curl -fsSL -X PUT -d @./unit-conf.json --unix-socket ./control.unit.sock "http://localhost/config/"
sudo tail -f ./access.log
おまけ: requirements.pip
Django==2.1.5
pytz==2018.9
ビルドとコンテナ起動
コンテナイメージのビルドをおこない、起動します。
curl等で疎通確認をおこないます。
$ docker build --no-cache ./ -t proj/api
$ docker run -d --name api -p 8080:8000 proj/api
$ curl http://localhost:8080/polls/
次の記事
ベースイメージ | 用途 | |
---|---|---|
NGINX Unit | APIサーバ | ○ |
mysql | MySQLサーバ | ←ココ |
redis | Redisサーバ | |
まとめる | docker compose |
- 上記イメージをDockerfileを記述してビルド
- Docker Composeで取りまとめる