* 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 ** 概要 [#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>)