リモコンを使わなくなったことに一抹の不安を覚える
もりもりです。
今回はFlaskアプリやサービスを作って公開する場合の運用環境についてです。
#01. Flaskアプリをdocker上で動かしてみる
#02. vscodeのRemote Developmentでデバッグしてみる
今回はこちら → #03. 運用環境を構築してみる
まずは
    第1回、第2回で作ったコンテナをそのままどこかのクラウドサービスへ
    デプロイしたらダメなの?というところですが
    公式ドキュメントでは以下のように書かれています。
    
When running publicly rather than in development,
you should not use the built-in development server (``flask run``).
The development server is provided by Werkzeug for convenience,
but is not designed to be particularly efficient, stable, or secure.
Instead, use a production WSGI server.
    ということのようです。
    flask runで実行した開発サーバーを本番環境で使用するべきではないと。
    効率性、安定性、セキュリティを意識して設計してはいないよと。
    
    代わりに本番環境ではWSGIサーバーを使ってねと。
    
    てなわけで、WebサーバーとAppサーバーを用意し
    WebサーバーとFlaskを繋ぐインターフェース
    WSGI (Web Server Gateway Interface) を利用して
    通信する環境をコンテナで作成していきます。
    
    今回使用するWSGIサーバーはuWSGIです。
    Flask + Docker + Nginx + uWSGI で環境を作っていきたいと思います。
    
    ちなみにWSGIの読み方は「ウィズギー」だそうです。
ディレクトリ構成
flask-product
  ├── app
  │ ├── Dockerfile
  │ ├── requirements.txt
  │ ├── run.py
  │ └── uwsgi.ini
  ├── web
  │ ├── Dockerfile
  │ └── nginx.conf
  └── docker-compose.yml
ソースコードはGithubにあります。
app/Dockerfile
WORKDIRを変更し、CMDを追加します。
# base image
FROM python:3.8.5
ARG project_dir=/var/www/
# workdir にファイル等追加
COPY requirements.txt $project_dir
# workdir
WORKDIR $project_dir
# upgrade pip
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
CMD ["uwsgi","--ini","/var/www/uwsgi.ini"]
追加した
CMDですが、
docker-compose.ymlに下記を追加しても問題ないと思います。(また試しときます。)
command: uwsgi --ini /var/www/uwsgi.ini
app/equirements.txt & run.py
uwsgiをインストールするので追加します。
Flask
uwsgi
app/uwsgi.ini
uWSGIの設定ファイルです。
[uwsgi]
wsgi-file = run.py
callable = app
master = true
processes = 1
socket = :3031
web/Dockerfile
公式イメージをベースとします。
# base image
FROM nginx:latest
CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
web/nginx.conf
Nginxの設定ファイルです。
user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
    upstream uwsgi {
        server app-server:3031;
    }
    server {
        listen 80;
        charset utf-8;
        location / {
            include uwsgi_params;
            uwsgi_pass uwsgi;
        }
    }
}
31行目のホスト名にはdocker-compose.ymlで指定したapp側のホスト名を指定します。
docker-compose.yml
コンテナをapp-serverとweb-serverの2つに分けます。
ホスト名も忘れずに設定しておきます。
version: "3"
services:
    app:
        container_name: app-server
        hostname: app-server
        build: ./app
        volumes:
            - "./app:/var/www/"
        ports:
            - "3031:3031"
        environment:
            TZ: Asia/Tokyo
  
    web:
        container_name: web-server
        hostname: web-server
        build: ./web
        volumes:
            - "./web/nginx.conf:/etc/nginx/nginx.conf"
            # nginxのログをホストOS側に出力
            - "/tmp/nginx_log:/var/log/nginx"
        links:
            - app
        ports:
            - "4231:80"
        environment:
            TZ: Asia/Tokyo
コンテナを起動して動作確認
$ docker-compose up -d
コンテナが起動すればブラウザから下記にアクセスするだけです。
http://localhost:4231
    はい、運用環境用のコンテナができました。
    あとはNginxやuWSGIの設定を本番用にちゃんと設定してから
    どこかのクラウドサービスへデプロイしてあげればよさそうですね。
以上、もりもりでした。
 
0 件のコメント:
コメントを投稿