Nginx+uwsgi+Flaskをdockerで動かす

概要

Nginx+wgsi+Flaskで動作させる為の Dockerイメージを作成する。
※下図の赤字部分に相当する dockerイメージを作成する

インターネット ⇔ Dockerホスト ⇔ Dockerコンテナ ⇔ Nginx ⇔ uwsgi ⇔ Flask

まずはローカルで uwsgi で動かしてみる

いったん uwsgi のみで動作するかローカルで確認する。

作業用フォルダの作成

まずは、作業用フォルダを作成する。
以降の作業は全てこのフォルダ配下で行う。

mkdir test_flask
cd test_flask

必要なものをインストール

python3 -m venv .venv
source .venv/bin/activate
pip install flask
pip install uwsgi

サンプルアプリケーションの作成

app/app.py

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'

uwsgiのみで動かしてみる

参考
https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html

uwsgi起動

uwsgi --http :3031 --wsgi-file app/app.py --callable app

確認

curl http://localhost:3031/
top page!(13:35:03.767707)

Dockerイメージ

ここからは実際に dockerイメージを作っていく。

フォルダ構成

静的ファイルを含めて全て /var/app 配下に配置する。
ただし、静的ファイルは uwsgi 経由でなく、Nginxが直接配信するように設定ファイルで調整する。

ローカルの作業フォルダ

.
├ Dockerfile
├ app
│   ├ app.py
│   ├ startup.sh
│   ├ static
│   │  └ style.css
│   └ templates
│       └ base.html
│       └ page.html
└ default.conf

作成するdockerイメージ

/var/app
 ├ app.py
 ├ startup.sh
 ├ static
 │   └ style.css
 └ templates
      └ base.html
      └ page.html
/etc/nginx/conf.d
 └ default.conf

アプリケーションの作成

app/app.py

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

<!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

{% extends "base.html" %}
{% block content %}
    <h1>{{page_name}}({{time}})</h1>
{% endblock %}

app/static/style.css

h1 {
    color: red;
}

起動用シェルの作成

app/startup.sh

#!/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;"

Nginxの設定ファイル作成

default.conf

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;
    }   
}

Dockerファイルの作成

Dockerfile

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"]

dockerイメージのビルド

docker build ./ -t app_nginx_uwsgi

dockerコンテナの起動

sudo docker run -p 8080:80 app_nginx_uwsgi

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-01-12 (土) 06:11:04 (1932d)