Python Flask kết hợp với uWSGI Nginx ssl Cerbot

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

nginx configuration with SSL, uwsgi


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. :))






Viết nhận xét

Các bạn có thể viết lời nhận xét cho bài viết, nhưng cần tuân thủ một số quy tắc sau:

» Các nhận xét/bình luận phải nghiêm túc, không dung tục, không spam.
» Nội dung phải liên quan tới chủ đề bài viết.
» Viết bằng tiếng việt có dấu hoặc tiếng Anh. Nội dung viết không dấu sẽ bị xóa.
» Hãy để lại tên của bạn khi nhận xét/bình luận, để tôi có thể dễ dàng trả lời bạn khi cần.