docker + nginx + uwsgi + flask の構築
環境
software | version |
---|---|
Ubuntu | 18.04 |
Docker | 18.09.0 |
docker-compose | 1.23.2 |
ディレクトリ構成
┣ myServer ┣ app ┣ Dockerfile ┣ main.py ┣ requirements.txt ┣ uwsgi.ini ┣ docker-compose.yaml ┣ nginx ┣ Dockerfile ┣ nginx.conf
1. docker-compose.yamlの作成
version: "3" services: uwsgi: # ビルドするDockerfileのでディレクトリ相対パス build: ./app # 指定したパスをコンテナにマウントする。"ホストのパス:コンテナのパス"となる volumes: - ./app:/var/www/ # 解放するポートを指定。"ホスト:コンテナ"のマッピング となる ports: - "3031:3031" # コンテナ内の環境変数を指定する environment: TZ: "Asia/Tokyo" nginx: build: ./nginx volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf # nginxのログをホストOSの /tmp/nginx_log に出力する - /tmp/nginx_log:/var/log/nginx links: - uwsgi ports: - "4231:80" environment: TZ: "Asia/Tokyo"
2. app の設定
Dockerfile
# ベースイメージ FROM python:3.6 RUN mkdir /var/www # workdirの指定 WORKDIR /var/www # 依存Pythonライブラリ一覧コピー COPY requirements.txt ./ # 依存Pythonライブラリインストール RUN pip install --no-cache-dir -r requirements.txt CMD ["uwsgi","--ini","/var/www/uwsgi.ini"]
--no-cache-dir
: キャッシュを無効にする-r
:requirements.txt
に記載されているパッケージを一括インストールする
main.py
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run()
requirements.txt
Flask uwsgi
uwsgi.ini
[uwsgi] wsgi-file = main.py callable = app master = true processes = 1 socket = :3031 chmod-socket = 666 vacuum = true die-on-term = true py-autoreload = 1
wsgi-file
: Flaskアプリケーションファイルcallable
: このファイル内のFlaskアプリケーションオブジェクトの名前master
: オプションを指定すると、アプリケーションサーバーとして起動したとき、ソケットを閉じずに再起動したりできるようにします。processes
: uWSGIの最大ワーカープロセス数socket
: WEBサーバとWEBアプリケーションをつなぐポートもしくはUNIXソケットファイルを指定するchmod-socket
: UNIXソケットのファイルパーミッション。指定が無い場合はデフォルトで 666 になるvacuum
: プロセス終了時に生成されたすべてのファイル/ソケットを削除するdie-on-term
: Upstartでプロセスが期待通りに処理されるために設定。uWSGIはプロセスを再ロードせずに強制終了します。py-autoreload
: コードの自動リロード機能。チェックサイクルごとにモジュールツリー全体をスキャンします。
余談
filesocket (/file/path/uwsgi.sock) を使った nginx -> uWSGI の通信の確立の仕方が分からなかった。
試したこと
- server unix:///tmp/uwsgi.sock
- server uwsgi:/tmp/uwsgi.sock
参考
3. nginx の設定
Dockerfile
FROM nginx CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
nginx.conf
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 uwsgi:3031; } server { listen 80; charset utf-8; location / { include uwsgi_params; uwsgi_pass uwsgi; } } }
4. dockerコンテナのビルドと実行
docker-compose.yaml と Dockerfile の内容に従ってコンテナをビルドする。
$ sudo docker-compose build Building uwsgi Step 1/6 : FROM python:3.6 ---> 1ec4d11819ad Step 2/6 : RUN mkdir /var/www ---> Using cache ---> 0cba8c49bdd8 Step 3/6 : WORKDIR /var/www ---> Using cache ---> 8d210dacf801 Step 4/6 : COPY requirements.txt ./ ---> Using cache ---> 21c64fe227f5 Step 5/6 : RUN pip install --no-cache-dir -r requirements.txt ---> Using cache ---> 2836363b7b84 Step 6/6 : CMD ["uwsgi","--ini","/var/www/uwsgi.ini"] ---> Using cache ---> 1f55d63545b3 Successfully built 1f55d63545b3 Successfully tagged myserver_uwsgi:latest Building nginx Step 1/2 : FROM nginx ---> 568c4670fa80 Step 2/2 : CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"] ---> Using cache ---> ac6b828f2312 Successfully built ac6b828f2312 Successfully tagged myserver_nginx:latest $
docker-compose.yaml のコンテナを実行する。
$ sudo docker-compose up -d Creating network "myserver_default" with the default driver Creating myserver_uwsgi_1 ... done Creating myserver_nginx_1 ... done $
-d
: バックグラウンドで実行する
実行中のdockerコンテナのプロセスを確認。
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 28901248f4c9 myserver_nginx "nginx -g 'daemon of…" 53 seconds ago Up 52 seconds 0.0.0.0:4231->80/tcp myserver_nginx_1 860cd0fe644e myserver_uwsgi "uwsgi --ini /var/ww…" 54 seconds ago Up 52 seconds 0.0.0.0:3031->3031/tcp myserver_uwsgi_1 $
nginx にアクセスして検証する。
表示できた。
$ cat /tmp/nginx_log/access.log xxx.xx.73.51 - - [20/Dec/2018:14:49:10 +0900] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 OPR/57.0.3098.91" "-" $
アクセスログもホストOSで確認することができた。