- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2019-01-08T09:46:56+00:00","","")
* Nginx+uwsgiでFlaskアプリケーション [#jfbc4dba]
* Nginx+uwsgi+Flaskをdockerで動かす [#ub9a05c1]
#setlinebreak(on)
#contents
-- 関連
--- [[Nginx]]
--- [[Flaskの基礎]]
--- [[dockerでサクッとNginx環境構築]]
-- 参考
--- https://nginx.org/en/
--- https://uwsgi-docs.readthedocs.io/en/latest/Nginx.html
--- https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html
#TODO
** 概要 [#gdd7ab34]
#html(<div style="padding-left:10px">)
Nginx+wgsi+Flaskで動作させる為の Dockerイメージを作成する。
※下図の赤字部分に相当する dockerイメージを作成する
#html(<div style="padding:0 10px; border: 1px solid #333; display: inline-block;">)
#html(インターネット ⇔ Dockerホスト ⇔ <span style="color:red">Dockerコンテナ ⇔ Nginx ⇔ uwsgi ⇔ Flask</span>)
#html(</div>)
#html(</div>)
** まずはローカルで uwsgi で動かしてみる [#c2cfa6dc]
#html(<div style="padding-left:10px">)
いったん uwsgi のみで動作するかローカルで確認する。
*** 作業用フォルダの作成 [#f3843d7b]
#html(<div style="padding-left:10px">)
まずは、作業用フォルダを作成する。
以降の作業は全てこのフォルダ配下で行う。
#myterm2(){{
mkdir test_flask
cd test_flask
}}
#html(</div>)
*** 必要なものをインストール [#hc230a8e]
#html(<div style="padding-left:10px">)
#myterm2(){{
python3 -m venv .venv
source .venv/bin/activate
pip install flask
pip install uwsgi
}}
#html(</div>)
*** サンプルアプリケーションの作成 [#v45b3e69]
#html(<div style="padding-left:10px">)
app/app.py
#mycode2(){{
from flask import Flask
import datetime
app = Flask(__name__)
@app.route('/')
def index():
now = datetime.datetime.now().strftime('%H:%M:%S.%f')
return f'<h1>top page!({now})</h1>\n'
@app.route('/sample')
def sample():
now = datetime.datetime.now().strftime('%H:%M:%S.%f')
return f'<h1>sample page!({now})</h1>\n'
}}
#html(</div>)
*** uwsgiのみで動かしてみる [#v450df85]
#html(<div style="padding-left:10px">)
参考
https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html
uwsgi起動
#myterm2(){{
uwsgi --http :3031 --wsgi-file app/app.py --callable app
}}
確認
#myterm2(){{
curl http://localhost:3031/
top page!(13:35:03.767707)
}}
#html(</div>)
#html(</div>)
** Dockerイメージ [#v9ce42ac]
#html(<div style="padding-left:10px">)
ここからは実際に dockerイメージを作っていく。
*** フォルダ構成 [#u0f943d6]
#html(<div style="padding-left:10px">)
静的ファイルを含めて全て /var/app 配下に配置する。
ただし、静的ファイルは uwsgi 経由でなく、Nginxが直接配信するように設定ファイルで調整する。
#html(<div style="display: inline-block; padding:0px 10px; margin-right:40px">)
ローカルの作業フォルダ
#html(<div style="border: 1px solid #333; padding:0px 10px;">)
.
├ Dockerfile
├ app
│   ├ app.py
│   ├ startup.sh
│   ├ static
│   │  └ style.css
│   └ templates
│     └ base.html
│     └ page.html
└ default.conf
#html(</div>)
#html(</div>)
#html(<div style="display: inline-block; padding:0px 10px; margin-right:40px; vertical-align: top">)
作成するdockerイメージ
#html(<div style="border: 1px solid #333; padding:0px 10px;">)
/var/app
├ app.py
├ startup.sh
├ static
│ └ style.css
└ templates
  └ base.html
  └ page.html
/etc/nginx/conf.d
└ default.conf
#html(</div>)
#html(</div>)
#html(</div>)
*** アプリケーションの作成 [#x3c82cc4]
#html(<div style="padding-left:10px">)
app/app.py
#mycode2(){{
rom flask import Flask, render_template
import datetime
app = Flask(__name__)
@app.route('/')
def index():
now = datetime.datetime.now().strftime('%H:%M:%S.%f')
return render_template('page.html', page_name='top page!', time=now)
@app.route('/sample')
def sample():
now = datetime.datetime.now().strftime('%H:%M:%S.%f')
return render_template('page.html', page_name='sample page!', time=now)
}}
app/templates/base.html
#mycode2(){{
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<head>
{% block head %}
<link rel="stylesheet" href="/static/style.css" />
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright Sample.
{% endblock %}
</div>
</body>
</html>
}}
app/templates/page.html
#mycode2(){{
{% extends "base.html" %}
{% block content %}
<h1>{{page_name}}({{time}})</h1>
{% endblock %}
}}
app/static/style.css
#mycode2(){{
h1 {
color: red;
}
}}
#html(</div>)
*** 起動用シェルの作成 [#p5cb6990]
#html(<div style="padding-left:10px">)
app/startup.sh
#mycode2(){{
#!/bin/bash
# アプリケーションディレクトリに移動
cd /var/app
# uwsgi起動
# TODO: rootで動かさない方が良いですよ。というWarningが出るので、ちゃんと uid 等を指定した方が良い
uwsgi --socket 127.0.0.1:3031 --chdir /var/app/ --wsgi-file app.py --callable app --master --processes 4 --threads 2 &
# nginx起動
nginx -g "daemon off;"
}}
#html(</div>)
*** Nginxの設定ファイル作成 [#ye0816cd]
#html(<div style="padding-left:10px">)
default.conf
#mycode2(){{
server {
listen 80;
server_name localhost;
root /var/app;
index index.html index.htm;
# Flaskアプリケーションは uwsgi に処理を任せる
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
# /static配下はNginxが直接配信
location ^~ /static/ {
include /etc/nginx/mime.types;
root /var/app;
}
}
}}
#html(</div>)
*** Dockerファイルの作成 [#c93a6c32]
#html(<div style="padding-left:10px">)
Dockerfile
#mycode2(){{
FROM ubuntu
USER root
# 必要なものをインストール
RUN apt-get update && \
apt-get -y install software-properties-common && \
add-apt-repository -y ppa:jonathonf/python-3.6 && \
apt-get update && \
apt-get -y install nginx && \
apt-get -y install python3.6-dev && \
apt-get -y install python3-pip
# PythonのPATH設定
RUN ln -s /usr/bin/python3.6 /usr/bin/python
RUN rm -rf /usr/bin/python3 && ln -s /usr/bin/python3.6 /usr/bin/python3
# flask、uwsgiをインストール
RUN pip3 install --upgrade pip && pip install flask && pip install uwsgi
# アプリケーションをコピー
COPY app /var/app
# Nginxの設定ファイルをコピー
COPY default.conf /etc/nginx/conf.d/default.conf
# 起動
CMD ["/bin/bash", "/var/app/startup.sh"]
}}
#html(</div>)
*** dockerイメージのビルド [#gf221cdc]
#html(<div style="padding-left:10px">)
#myterm2(){{
docker build ./ -t app_nginx_uwsgi
}}
#html(</div>)
*** dockerコンテナの起動 [#xbf19f49]
#html(<div style="padding-left:10px">)
#myterm2(){{
sudo docker run -p 8080:80 app_nginx_uwsgi
}}
#html(</div>)
#html(</div>)