Deploy flask บน linux server ด้วย Gunicorn, Nginx, Supervisor ง่ายๆ
บทความนี้จะเกี่ยวกับการ deploy ขึ้น production อย่างเดียวนะ
ส่วนเนื้อหาเกี่ยวกับ linux server, flask และอื่น ๆ จะขอไม่เน้น
ในบทความนี้ ตัว linux server ผมจะใช้ Raspberry PI 3B
ส่วนเว็บผมในบทความนี้มีชื่อว่า flask_web นะครับ
directory tree จะอยู่ประมาณนี้
/home/pi/webs/flask_web
├── env
├── instance
├── flask_web
│ ├── blueprints
│ ├── static
│ └── templates
├── flask_web.egg-info
├── requirements.txt
├── run-web
├── run-web-win10.bat
└── setup.py
ก่อนอื่นต้องติดตั้ง Gunicorn โดยติดตั้งใน enviorment ของ web
(application server สำหรับ python ของเรา)
(env) $ pip install gunicorn
จากนั้นก็ต้องมี Nginx และ Supervisor ก่อนหากยังไม่ให้ติดตั้งก่อน
(reverse proxy และ procress control system)
$ sudo apt install nginx supervisor
แล้วลบของเดิมออก จากนั้นสร้างไฟล์ของ web เรา
**ควรตั้งชื่อไฟล์ให้เป็นชื่อเดียวกับเว็บจะได้ไม่สับสนในที่นี้ผมใช้ flask_web
editor ก็แล้วแต่สะดวกใช้ nano หรือ vi ที่มีติดเครื่องก็ได้
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo vim /etc/nginx/sites-enabled/flask_web
แล้วแปะตัวนี้ลงไปเลย
server {
listen 80;
server_name karn.com;location /static {
alias /home/pi/webs/flask_web/flask_web/static;
}location / {
proxy_pass http://localhost:8000;
include /etc/nginx/proxy_params;
proxy_redirect off;
}
}
อธิบาย
— listen คือ port ของ web (80 คือ http)
— server_name คือ ชื่อ domain หรือ ip ของเว็บ
อย่างในตัวอย่างนี้เมื่อผู้ใช้จะเข้าเว็บก็จะต้องเข้าผ่าน karn.com:80 หรือ karn.com
— location /static จะเป็นตัวบอกทางไป static ของเว็บ
— location / คือตัวบอกทางเมื่อเข้ามาที่เว็บเราโดยในที่นี้จะไปพาไปยัง gunicorn ด้วย proxy_pass ซึ่ง Default port ของ Gunicorn อยู่ที่ 8000
$ sudo systemctl restart nginx
สร้าง service ของเว็บเราบน Supervisor
$ sudo vim /etc/supervisor/conf.d/flask_web.conf
แปะ
[program:flask_web]
directory=/home/pi/webs/flask_web
command=/home/pi/webs/flask_web/env/bin/gunicorn -w 9 "flask_web:create_app()"
user=pi
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stderr_logfile=/var/log/flask_web/err.log
stdout_logfile=/var/log/flask_web/out.log
อธิบาย
— directory คือที่อยู่ของเว็บ
— command คำสั่งที่เราจะใช้รันเว็บโดยใช้ gunicorn
** -w คือ จำนวน worker (load balancing when handling requests)
ที่แนะนำคือควรจะเป็น (2 x $num_cores) + 1
Ex. RPi ผมมี 4 cores worker ก็คือ 9
— “flask_web:create_app()”
หากไม่ได้ใช้ factory pattern ให้สร้างไฟล์สำหรับรันขึ้นมาตัวหนึ่ง (อยู่ท้ายบทความ)
— user คือ ชื่อ user ของเรา
— ที่เหลือก็ประมาณเมื่อล่มให้เริ่มใหม่และเขียน log ต่างๆ
อย่าลืมสร้างไฟล์ไว้เก็บ Log ด้วย
$ sudo touch /var/log/flask_web/err.log
$ sudo touch /var/log/flask_web/out.log
จากนั้น restart supervisor
$ sudo supervisorctl reload
เป็นอันเสร็จครับ เย่ ที่เหลือสามารถปรับแต่งได้ เช่น ให้เว็บยอมรับไฟล์ที่มีขนาดมากกว่า 2 MB โดยแก้ที่ Nginx
แล้วเจอกันครับ :)
— หากไม่ได้ใช้ factory pattern ให้สร้างไฟล์สำหรับรันขึ้นมาตัวหนึ่ง
เช่น
.
├── flask_web.py
├── run.py
flask_web.py
# flask_web.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "this is my first page"
if __name__ == "__main__":
app.run(host='0.0.0.0')
สร้างตัวรันตัวนี้ขึ้นมา ผมให้ชื่อว่า run.
ประมาณว่า flask_web.py ไว้รัน develop ส่วน run.py ไว้รัน production แต่ผมแนะนำว่าทำเป็น factory pattern ดีกว่าครับ
# run.py
from flask_web import app
if __name__ == "__main__":
app.run()
แล้วแก้เป็น “run:app”
แทน
gunicorn -w 9 run:app
REF : Python Flask Tutorial: Deploying Your Application (Option #1) — Deploy to a Linux Server