* 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
│&#160;&#160; ├ app.py
│&#160;&#160; ├ startup.sh
│&#160;&#160; ├ static
│&#160;&#160; │&#160;&#160;└ style.css
│&#160;&#160; └ templates
│&#160;&#160;&nbsp;&nbsp;&nbsp;&#160;&#160;└ base.html
│&#160;&#160;&nbsp;&nbsp;&nbsp;&#160;&#160;└ 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
&nbsp;├ app.py
&nbsp;├ startup.sh
&nbsp;├ static
&nbsp;│&nbsp;&nbsp;&nbsp;└ style.css
&nbsp;└ templates
&nbsp;&nbsp;&nbsp;&nbsp;&#160;&#160;└ base.html
&nbsp;&nbsp;&nbsp;&nbsp;&#160;&#160;└ page.html
/etc/nginx/conf.d
&nbsp;└ 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 %}
        &#169; Copyright Sample.
        {% endblock %}
    </div>
</body>
</html>
}}

app/templates/page.html
#mycode2(){{
{% extends "base.html" %}
{% block content %}
    <h1>&#123;&#123;page_name&#125;&#125;(&#123;&#123;time&#125;&#125;)</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>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS