🎉

FlaskアプリのデプロイにGunicornを使用してみる

2023/04/28に公開約5,000字

概要

Python(Flask)とGunicornを用いたアプリを構築してみます。

1. Flaskでアプリを作成してみよう

ディレクトリ

.
├─ tamplates
    ├─ indes.html
├─ app.py
├─ Dockerfile
├─ gunicorn.py
└─ requirements.txt

ソースコード

app.pyの内容は以下になります。

py
from flask import Flask, render_template

app = Flask(__name__)

@app.get('/')
def index():
    return render_template('index.html')
html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>Python Web App - Welcome</title>
    <link href="https://appservice.azureedge.net/css/app-service/v4/bootstrap.min.css" rel="stylesheet"crossorigin="anonymous" />
    <style>
        html,
        body {
            height: 100%;
            color: #000000;
            font-size: 13px;
            padding: 1rem 2rem;
            background-image: -webkit-linear-gradient(315deg, #231557 0%, #44107a 29%, #ff1361 67%, #fff800 100%);
            background-image: linear-gradient(-225deg, #231557 0%, #44107a 29%, #ff1361 67%, #fff800 100%);
        }

        * {
            border-radius: 0 !important;
        }

        .top span {
            background-image: -webkit-gradient(linear, right top, left top, from(#e14fad), to(#f9d423));
            background-image: -webkit-linear-gradient(right, #e14fad 0%, #f9d423 100%);
            background-image: linear-gradient(to left, #e14fad 0%, #f9d423 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
    </style>
</head>

<body>
    <nav class="navbar">
        <div class="navbar-brand ">
            <div class="container pl-4 ml-5">
                <h1 class="top"><span>Your Web App<span></h1>
            </div>
        </div>
    </nav>
    <div class="container-fluid mr-2 mt-5 pt-5">
        <div class="row">
            <div class="col-xs-12 col-sm-12 d-block d-lg-none d-xl-none d-md-block d-sm-block d-xs-block">
                <div class="text-center"><img src="https://appservice.azureedge.net/images/app-service/v4/web.svg" />
                </div>
            </div>
            <div class="pl-5 ml-5 col-xl-5 col-lg-5 col-md-10 col-sm-11 col-xs-11">
                <div class="container-fluid">
                    <div class="row">
                        <h2 id="upRunning">Your web app is running and waiting for your content</h2>
                    </div>
                </div>
            </div>
            <div class="col-xl-5 col-lg-5 col-md-12 d-none d-lg-block">
                <div class="text-left"><img src="https://appservice.azureedge.net/images/app-service/v4/web.svg" />
                </div>
            </div>
            <div class="col-xl-1 col-lg-1 col-md-1"></div>
        </div>
    </div>
</body>
</html>

実行

まずは仮想環境(venv)を用いて実行してみる。

  1. venvを作成 -> アクティブ化
sh
python -m venv venv 
  1. ライブラリインストール
sh
# mac or Linux
source venv/bin/activate
  1. ライブラリのインストール
pip install flask
  1. 実行
flask --app app:app run
  1. http://localhost:8000 をブラウザで開くとアクセスできるはず!

https://flask.palletsprojects.com/en/2.3.x/

2. Gunicornでデプロイしてみよう

  1. gunicornをインストールする。
pip install gunicorn
  1. gunicornの設定ファイル作成
import os

# UNIXドメインソケット
socket_path = 'unix:/tmp/gunicorn_socket/gunicorn_flask.sock'
# TCPソケット
socket_path = '0.0.0.0:' + str(os.getenv('PORT', 8000))
bind = socket_path

# Debugging
reload = True

# Logging
accesslog = '-'
#loglevel = 'info'
loglevel = 'debug'
logfile = './log/app.log'
logconfig = None

# Proc Name
proc_name = 'Infrastructure-Practice-Flask'

# Worker Processes
workers = 2
worker_class = 'sync'
  1. gunicorn実行
gunicorn app:app --config gunicorn.py
  1. http://localhost:8000 をブラウザで開くとアクセスできるはず!

https://docs.gunicorn.org/en/latest/index.html

3. Dockerで実行してみよう

Dockerfileの内容を以下とします。とりあえず、最小構成で作成します。

# Pythonのバージョンを指定
ARG VERSION=3.10
# ベースイメージを指定
FROM python:$VERSION
ENV PYTHONUNBUFFERED=1

WORKDIR /usr/app
COPY . .

RUN apt-get update
# ライブラリをインストール
RUN pip install -r requirements.txt
# 8000 ポートを開放予定
EXPOSE 8000
ENTRYPOINT ["gunicorn", "app:app", "--config", "gunicorn.py" ]

pythonライブラリを Docker にインストールするために requirements.txtを作成します。そのため以下のコマンドを実行してインストールしているライブラリをファイルに吐き出します。

pip freeze > requirements.txt

requirements.txtに以下のように吐き出されます。

blinker==1.6.2
click==8.1.3
Flask==2.3.1
gunicorn==20.1.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.2
Werkzeug==2.3.1

※ ここでvenvがアクティブになっている場合、deactivateで非アクティブ化します。(venvディレクトリはいらないので削除してOK)

それでは、Dockerで実行してみます。

  1. Docker Image を作成
docker image build -t <tag-name> .

<tag-name>はご自由に!!
2. Docker Container を立ち上げる

docker run --name flask-webapp -p 8000:8000 <tag-name>

先ほどDockerfileEXPOSE 8000で8000ポートを開けると記載したので、上記コマンドで実際に8000ポートを開けます。これを指定しないとアクセスできない。
3. http://localhost:8000/ にアクセスすると先ほどのページが開かれるはず!!

まとめ

とりあえず、[client -> gunicorn -> flask]構成をDockerに構築することができました。何かの役に立てればと思います!!

Discussion

ログインするとコメントできます