Flask使ってアプリケーション作ったのはいいけど、デプロイ面倒くさいなぁって思っている人向け。
# python run.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Flaskの公式ドキュメント http://flask.pocoo.org/docs/1.0/quickstart/ には
This launches a very simple builtin server, which is good enough for testing but probably not what you want to use in production. For deployment options see Deployment Options.
開発用サーバはテスト用には十分だけど、本番環境では非推奨って書いてあるので、rDockerを使って楽をしようと思った。
TL;DR
https://github.com/lboavde1121/flaskapp
make run
上記コマンド1つで、Flask+uwsgi+nginxの環境をDockerに構築します。
読むのが面倒な方は、上のリポジトリをクローンしてmake run
してください。
イメージとしては、
Docker <-> nginx <-> uwsgi <-> Flask
こんな感じ。
気が向いたらお絵かきします。
動作環境
- MacOS
- Windows
- Linux(EC2 AmazonLinux)
で動作確認済み。
※下記ツールversion等はMacOS
今回の主役Docker
- Docker : 18.03.0-ce
- Docker-compose : 1.20.1
そしてビルド→起動を1コマンドにするためにmake
- make : GNU Make 3.81
※Windows10 Pro以外のWindowsはDocker Toolbox使おう。
https://docs.docker.com/toolbox/toolbox_install_windows/
構成
Flask部分(./app/src配下)は大したことしてないので今回触れません。
Githubに全部あげてるのでそちらからどうぞ。
.
├── Makefile
├── README.md
├── app
│ ├── Dockerfile
│ ├── requirements.txt
│ ├── src
│ │ ├── config
│ │ │ ├── __init__.py
│ │ │ └── default.py
│ │ ├── run.py
│ │ ├── server
│ │ │ ├── __init__.py
│ │ │ └── hoge
│ │ │ ├── __init__.py
│ │ │ └── hoge_api.py
│ │ └── tests
│ │ ├── __init__.py
│ │ └── test_hoge.py
│ └── uwsgi.ini
├── docker-compose.yml
└── nginx
├── Dockerfile
└── nginx.conf
docker-compose
初めは、1コンテナで構築しようと思っていたが、nginxとかPythonインストールとか面倒だったのでDocker-composeを使って
- nginx
- Flask+uwsgi
上記2コンテナをSocketで繋いだ。
以下docker-composeの設定ファイル
version: "2"
services:
uwsgi:
build: ./app
volumes:
- ./app:/var/www/
ports:
- "3031:3031"
environment:
TZ: "Asia/Tokyo"
nginx:
build: ./nginx
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
links:
- uwsgi
ports:
- "4231:80"
environment:
TZ: "Asia/Tokyo"
Flaskコンテナ(uwsgi)にapp/*
nginxコンテナにnginx/nginx.conf
をマウント。
nginxコンテナ
次はnginxコンテナのDockerfile。
# ベースイメージの設定
FROM nginx
CMD ["nginx", "-g", "daemon off;","-c","/etc/nginx/nginx.conf"]
nginx起動のコマンドは「RUN」ではなく「CMD」or「ENTRYPOINT」で起動する。(当たり前だけど)
※「CMD」or「ENTRYPOINT」はここ参考
Flaskとuwsgiで繋ぐためにnginxの設定ファイル(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;
}
location /static {
alias /static;
}
location /media {
alias /media;
}
}
}
Flask+uwsgiコンテナ
以下Flaskコンテナの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
WORKDIR /var/www/src
CMD ["uwsgi","--ini","/var/www/uwsgi.ini"]
Dockerのマウントのタイミングが、
起動時(ビルド時は未マウント)
のようで、ビルド時に必要なファイル(requirements.txt)はビルド時にコピー(Dockerfile内に明示的に記載する)必要がある。
そして、nginxとFlaskを繋ぐuwsgiの設定ファイル。
[uwsgi]
wsgi-file = /var/www/src/run.py
callable = app
master = true
processes = 1
socket = :3031
chmod-socket = 666
vacuum = true
die-on-term = true
py-autoreload = 1
py-autoreload = 1
これを書いておくと、ソース修正したときに自動でリロードしてくれる。
Makefile
NAME=flaskapp
run:
docker-compose build
docker-compose up -d
stop:
docker stop ${NAME}_uwsgi_1 ${NAME}_nginx_1
docker rm ${NAME}_uwsgi_1 ${NAME}_nginx_1
これだけ。
さぁ! 1コマンドで実行だ!!
# make run
# make run
docker-compose build
Building uwsgi
Step 1/7 : FROM python:3.6
---> efb6baa1169f
Step 2/7 : RUN mkdir /var/www
---> Using cache
---> 00445d785d14
Step 3/7 : WORKDIR /var/www
---> Using cache
---> 215c53d71716
Step 4/7 : COPY requirements.txt ./
---> Using cache
---> cabb91df7ca0
Step 5/7 : RUN pip install --no-cache-dir -r requirements.txt
---> Using cache
---> 62f2a1a976d4
Step 6/7 : WORKDIR /var/www/src
---> Using cache
---> aaee265830d6
Step 7/7 : CMD ["uwsgi","--ini","/var/www/uwsgi.ini"]
---> Using cache
---> db35ff6f215b
Successfully built db35ff6f215b
Successfully tagged flaskapp_uwsgi:latest
Building nginx
Step 1/2 : FROM nginx
---> b175e7467d66
Step 2/2 : CMD ["nginx", "-g", "daemon off;","-c","/etc/nginx/nginx.conf"]
---> Using cache
---> 036cf8c36459
Successfully built 036cf8c36459
Successfully tagged flaskapp_nginx:latest
docker-compose up -d
Creating flaskapp_uwsgi_1 ... done
Creating flaskapp_nginx_1 ... done
おしまい
実際はもっと設定必要だと思います。
DBはRDS想定なので構築しませんでしたが、同じようなノリでいけると信じています。
質問やフィードバックお待ちしています。
Twitter: https://twitter.com/rt_s2t