Bình thường khi viết xong app Python Flask thì chúng ta thường chạy bằng lệnh:
python3 myproject.py
Giờ, chúng ta sẽ chạy qua uWSGI và Nginx sử dụng SSL cho nó...chuẩn nhé!
Phần I: Chạy web với HTTP thuần
Step 1: Cài các gói cần thiết và chạy thử Python Flask App
Đầu tiên, cần cài các gói cần thiết:
yum install epel-release
Nếu dùng centos8/Rocky Linux thì có thể cài qua lệnh:
dnf install epel-release
yum install python-pip python-devel gcc nginx
Tạo Python Virtual Environment:
pip install virtualenv
mkdir ~/myproject
cd ~/myproject
virtualenv myprojectenv
source myprojectenv/bin/activate
Cài đặt Flask và uWSGI:
pip install uwsgi flask
Tạo cái app mẫu nào:
vim ~/myproject/myproject.py
Nội dung:
from flask import Flask
application = Flask(__name__)
@application.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
application.run(host='0.0.0.0', port=5001)
Chạy test:
python3 myproject.py
Truy cập thử web với port:5001 nếu ra "Hello There!" là ok, chưa ok thì xem mở port trong firewalld...
Nếu chưa mở port thì mở như sau:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Tạo WSGI Entry Point:
vim ~/myproject/wsgi.py
from myproject import application
if __name__ == "__main__":
application.run()
Chạy thử uWSGI Serving:
uwsgi --socket 0.0.0.0:5001 --protocol=http -w wsgi
Truy cập thử web với port:5001 nếu ra "Hello There!" là ok.
Xong, sứ mệnh của virtual environment đã kết thúc, tắt nó:
deactivate
Step 2: Tạo các cấu hình chạy dịch vụ cho uWSGI
- Tạo file cấu hình cho uWSGI:
vim ~/myproject/myproject.ini
Nội dung:
[uwsgi]
module = wsgi
master = true
processes = 5
socket = myproject.sock
chmod-socket = 660
vacuum = true
die-on-term = true
Tạo file chạy service:
vim /etc/systemd/system/myproject.service
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
[Service]
User=webuser
Group=nginx
WorkingDirectory=/home/user/myproject
Environment="PATH=/home/user/myproject/myprojectenv/bin"
ExecStart=/home/user/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
[Install]
WantedBy=multi-user.target
- Khởi chạy dịch vụ:
systemctl daemon-reload
sudo systemctl start myproject
sudo systemctl enable myproject
Step 3: Cấu hình Nginx Proxy
vim /etc/nginx/conf.d/lecuong.info.conf
Nội dung:
server {
listen 80;
server_name lecuong.info;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/user/myproject/myproject.sock;
}
}
Thêm webuser vào nhóm nginx
sudo usermod -a -G webuser nginx
chmod 710 /home/webuser # ko chay lenh nay khi truy cap web se ra loi: 502 Bad Gateway
- Kiểm tra cấu hình Nginx
sudo nginx -t
Nếu nó không lòi ra lỗi gì, thì ngon lành rồi đó! Còn nếu có lỗi thì...tìm cách sửa đi :))
Khởi chạy dịch vụ Nginx:
sudo systemctl start nginx
sudo systemctl enable nginx
Rồi, xong rồi đó. Truy cập web ngon lành nha!
(*) phần này cần tham khảo chi tiết thì xem ở đây
Phần II: Chạy web với HTTPS cho nó bảo mật nha :))
Step 1: Cài đặt cerbot và Nginx plugin dùng cho cerbot
sudo dnf install certbot python3-certbot-nginx
- Tiến hành tạo Cert:
sudo certbot --nginx -d lecuong.info -d www.lecuong.info
Nếu chỉ cần tạo cert cho 1 dommain duy nhất thì gõ:sudo certbot --nginx -d your_domain
Nếu thành công thì certbot nó sẽ thông báo dạng "Congratulations! Your certificate and chain have been saved at:"
Còn nếu lỗi gì đó, thì debug từ từ giải quyết thôi :))
- Cấu hình tự động renew cert SSL (vì mặc định cert sẽ hết hạn sau 90 ngày.):
Test thử xem việc renew có ok ko?
certbot renew --dry-run
Nếu ok thì cài đặt job cho nó tự renew:
crontab -e
dán vô:
* */12 * * * root /usr/bin/certbot renew >/dev/null 2>&1
Step 2: cấu hình SSL vô web
Mặc định certbot nó ghi sẵn vô /etc/nginx/nginx.conf rồi, nhưng tôi thích dùng file cấu hình riêng hơn!
vim /etc/nginx/conf.d/lecuong.info.conf
server {
server_name lecuong.info;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/user/myproject/myproject.sock;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/lecuong.info/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lecuong.info/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
- Khởi động lại dịch vụ Flask web và Nginx
systemctl restart myproject
systemctl restart nginx
Nhiêu đó là xong rồi.
Từ giờ, chúng ta có thể truy cập web với https://
Cơm thêm: Nếu bạn nào dùng dịch vụ CloudFlare, và có bật Proxy thì cần đổi cấu hình thì mới chạy được!
Chia sẻ file cấu hình nè: ngix_proxy_behind_cloudflare.conf
Thêm nữa là nếu chạy test renew certbot lỗi thì nên thêm các page rule trên Cloudflare
# This is a Cloudflare issue as it's caching the response.
*yourdomain.com/.well-known/acme-challenge/*
Cache Level: Bypass, Automatic HTTPS Rewrites: Off, Disable Performance
Chúc các bạn may mắn. :))