Hướng Dẫn Triển Khai Flask Gunicorn Nginx Trên Ubuntu 20.04

Khi bạn xây dựng xong một ứng dụng web với Flask, bước tiếp theo chính là đưa nó lên môi trường sản xuất để người dùng có thể truy cập. Việc triển khai một ứng dụng web bền vững và hiệu quả là yếu tố then chốt quyết định sự thành công của dự án. Tuy nhiên, nhiều nhà phát triển thường gặp khó khăn khi chạy ứng dụng Flask trực tiếp trên môi trường production. Việc sử dụng máy chủ phát triển tích hợp sẵn của Flask không đủ mạnh mẽ, an toàn và không thể xử lý nhiều yêu cầu đồng thời.

Đây chính là lúc Gunicorn và Nginx là gì phát huy vai trò của mình. Gunicorn hoạt động như một máy chủ WSGI mạnh mẽ, giúp ứng dụng Flask của bạn chạy ổn định, trong khi Nginx đóng vai trò là một reverse proxy, giúp tăng cường hiệu suất và bảo mật. Bài viết này sẽ hướng dẫn bạn từng bước cách thiết lập môi trường Ubuntu 20.04, cài đặt Gunicorn, cấu hình Nginx và tối ưu hóa để triển khai ứng dụng Flask một cách chuyên nghiệp.

Cài đặt môi trường Ubuntu 20.04 cho ứng dụng Flask

Để bắt đầu, chúng ta cần chuẩn bị một nền tảng vững chắc cho ứng dụng. Việc thiết lập một môi trường sạch và đúng chuẩn trên Ubuntu 20.04 là bước đầu tiên và quan trọng nhất.

Chuẩn bị hệ thống và cập nhật gói

Trước tiên, hãy đảm bảo hệ điều hành của bạn được cập nhật lên phiên bản mới nhất. Điều này giúp vá các lỗ hổng bảo mật và cải thiện tính ổn định. Mở terminal và chạy các lệnh sau:

sudo apt update && sudo apt upgrade

Tiếp theo, chúng ta cần cài đặt Python, trình quản lý gói pip và công cụ để tạo môi trường ảo. Hầu hết các phiên bản Ubuntu 20.04 đã có sẵn Python 3, nhưng bạn nên cài đặt đầy đủ các gói cần thiết.

sudo apt install python3 python3-pip python3-venv

Sau khi cài đặt xong, bước cực kỳ quan trọng là thiết lập một môi trường ảo (virtual environment). Tại sao điều này lại cần thiết? Môi trường ảo giúp cô lập các thư viện và gói phụ thuộc của dự án, tránh xung đột với các dự án khác trên cùng một máy chủ.

Để tạo môi trường ảo, hãy tạo một thư mục cho dự án của bạn và di chuyển vào đó.
mkdir myproject && cd myproject
Bên trong thư mục dự án, hãy chạy lệnh sau để tạo môi trường ảo có tên là venv:
python3 -m venv venv
Cuối cùng, hãy kích hoạt môi trường ảo này:
source venv/bin/activate
Bạn sẽ thấy tên môi trường ảo (venv) xuất hiện ở đầu dòng lệnh, cho biết bạn đang làm việc bên trong nó.

Hình minh họa

Cài đặt Flask và tạo ứng dụng mẫu

Khi đã ở trong môi trường ảo, việc cài đặt Flask trở nên rất đơn giản. Bạn chỉ cần sử dụng pip để cài đặt.

pip install Flask

Bây giờ, hãy tạo một ứng dụng Flask đơn giản để kiểm tra. Tạo một file mới có tên app.py với nội dung sau:

nano app.py

Dưới đây là đoạn mã cho một ứng dụng “Hello, World!” cơ bản:

“`python
from flask import Flask

app = Flask(__name__)

@app.route(“/”)
def hello():
return “<h1>Chào mừng bạn đến với ứng dụng Flask!</h1><p>Được triển khai với Gunicorn và Nginx.</p>”

if __name__ == “__main__”:
app.run(host=”0.0.0.0″)
“`

Đoạn mã này tạo ra một ứng dụng web đơn giản. Khi người dùng truy cập vào trang chủ, nó sẽ trả về một lời chào. Đây sẽ là ứng dụng mẫu chúng ta sử dụng để kiểm tra trong suốt quá trình cài đặt.

Hình minh họa

Cài đặt và cấu hình Gunicorn làm máy chủ WSGI

Máy chủ phát triển của Flask không được thiết kế cho môi trường sản xuất. Chúng ta cần một máy chủ WSGI (Web Server Gateway Interface) thực thụ, và Gunicorn là một trong những lựa chọn phổ biến và mạnh mẽ nhất.

Cài đặt Gunicorn

Vì chúng ta đã ở trong môi trường ảo, việc cài đặt Gunicorn cũng rất dễ dàng. Gunicorn sẽ quản lý và chạy ứng dụng Flask của bạn một cách hiệu quả.

Hãy chạy lệnh sau để cài đặt Gunicorn:
pip install gunicorn

Sau khi cài đặt hoàn tất, bạn có thể kiểm tra phiên bản Gunicorn để đảm bảo nó đã được cài đặt thành công.
gunicorn --version

Gunicorn là một máy chủ HTTP WSGI được viết bằng Python cho các hệ thống UNIX. Nó là cầu nối trung gian giữa ứng dụng web của bạn và máy chủ web (như Nginx), giúp xử lý các yêu cầu từ client một cách hiệu quả.

Hình minh họa

Chạy Flask ứng dụng qua Gunicorn

Bây giờ, thay vì chạy ứng dụng bằng lệnh python app.py, chúng ta sẽ sử dụng Gunicorn. Điều này cho phép ứng dụng của bạn xử lý nhiều kết nối cùng lúc và hoạt động ổn định hơn.

Để chạy ứng dụng Flask với Gunicorn, bạn sử dụng lệnh sau:
gunicorn --bind 0.0.0.0:5000 app:app

Hãy phân tích lệnh này một chút. app:app có nghĩa là “trong file app.py, hãy tìm đối tượng ứng dụng có tên là app“. --bind 0.0.0.0:5000 yêu cầu Gunicorn lắng nghe các kết nối trên cổng 5000 từ mọi địa chỉ IP.

Một trong những ưu điểm lớn nhất của Gunicorn là khả năng chạy đa tiến trình (workers) để tối ưu hóa hiệu suất. Bạn có thể chỉ định số lượng worker khi khởi động. Một công thức phổ biến để bắt đầu là (2 * số lõi CPU) + 1.

Ví dụ, nếu máy chủ của bạn có 2 lõi CPU, bạn có thể chạy:
gunicorn --workers 5 --bind 0.0.0.0:5000 app:app
Việc này sẽ tạo ra 5 tiến trình worker, cho phép ứng dụng của bạn xử lý 5 yêu cầu của người dùng cùng một lúc, cải thiện đáng kể khả năng đáp ứng của trang web.

Cấu hình Nginx làm reverse proxy cho ứng dụng Flask

Mặc dù Gunicorn rất mạnh mẽ trong việc phục vụ ứng dụng Flask, nó không được tối ưu để đối mặt trực tiếp với lưu lượng truy cập từ internet. Đây là lúc Nginx, một máy chủ web hiệu suất cao, phát huy vai trò của mình như một reverse proxy.

Cài đặt và thiết lập Nginx trên Ubuntu

Nginx sẽ đứng trước Gunicorn, nhận các yêu cầu từ người dùng và chuyển tiếp chúng đến Gunicorn. Nó cũng có thể xử lý các tác vụ như phục vụ các file tĩnh (CSS, JavaScript, hình ảnh), nén dữ liệu và mã hóa SSL.

Để cài đặt Nginx trên Ubuntu, hãy chạy lệnh sau:
sudo apt install nginx

Sau khi cài đặt xong, Nginx thường sẽ tự động khởi động. Bạn có thể kiểm tra trạng thái của dịch vụ để chắc chắn.
sudo systemctl status nginx
Nếu dịch vụ đang chạy, bạn có thể truy cập địa chỉ IP của máy chủ trên trình duyệt và sẽ thấy trang chào mừng mặc định của Nginx.

Hình minh họa

Tiếp theo, chúng ta cần tạo một file cấu hình server block riêng cho ứng dụng Flask của mình. Điều này cho phép bạn quản lý cấu hình của từng trang web một cách độc lập.
sudo nano /etc/nginx/sites-available/myproject

Kết nối Nginx với Gunicorn

Bên trong file cấu hình myproject, bạn hãy dán đoạn mã sau. Đừng quên thay thế your_domain_or_ip bằng tên miền hoặc địa chỉ IP của bạn.

server {
listen 80;
server_name your_domain_or_ip;

location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Đoạn cấu hình này yêu cầu Nginx lắng nghe trên cổng 80. Khi có yêu cầu đến, proxy_pass http://127.0.0.1:8000; sẽ chuyển tiếp yêu cầu đó đến Gunicorn, mà chúng ta sẽ cấu hình để chạy trên cổng 8000.

Sau khi lưu file, bạn cần kích hoạt cấu hình này bằng cách tạo một liên kết tượng trưng từ sites-available đến sites-enabled.
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Để đảm bảo không có lỗi cú pháp, hãy kiểm tra lại file cấu hình Nginx:
sudo nginx -t
Nếu kết quả trả về là syntax is ok, bạn có thể khởi động lại Nginx để áp dụng các thay đổi.
sudo systemctl restart nginx

Hình minh họa

Chạy và kiểm tra hoạt động ứng dụng Flask trên Ubuntu

Sau khi đã cấu hình Gunicorn và Nginx, giờ là lúc kết hợp chúng lại và kiểm tra xem ứng dụng của chúng ta có hoạt động như mong đợi không.

Đầu tiên, hãy đảm bảo bạn đang ở trong thư mục dự án và môi trường ảo đã được kích hoạt. Chạy ứng dụng Flask bằng Gunicorn, nhưng lần này chúng ta sẽ cho nó chạy trên cổng 8000, cổng mà Nginx đang lắng nghe để chuyển tiếp.
gunicorn --workers 3 --bind 127.0.0.1:8000 app:app

Lưu ý rằng chúng ta đang bind Gunicorn với 127.0.0.1 thay vì 0.0.0.0. Điều này có nghĩa là Gunicorn sẽ chỉ chấp nhận kết nối từ chính máy chủ đó (localhost), và Nginx là dịch vụ duy nhất có thể giao tiếp với nó. Đây là một biện pháp bảo mật quan trọng.

Sau khi Gunicorn đã chạy, hãy mở trình duyệt và truy cập vào địa chỉ IP hoặc tên miền của máy chủ. Nếu mọi thứ được cấu hình chính xác, bạn sẽ thấy thông điệp chào mừng từ ứng dụng Flask của mình. Yêu cầu của bạn đã đi từ trình duyệt -> Nginx -> Gunicorn -> ứng dụng Flask và quay trở lại.

Hình minh họa

Để xác nhận mọi thứ hoạt động trơn tru, bạn có thể kiểm tra các file log. Log của Nginx thường nằm ở /var/log/nginx/access.log/var/log/nginx/error.log. Các thông báo từ Gunicorn sẽ hiển thị trực tiếp trên terminal nơi bạn đã chạy nó.

Xử lý sự cố và tối ưu hiệu năng cho Gunicorn và Nginx

Trong quá trình triển khai, việc gặp lỗi là điều khó tránh khỏi. Hiểu rõ các lỗi phổ biến và cách khắc phục sẽ giúp bạn tiết kiệm rất nhiều thời gian và công sức.

Các lỗi phổ biến khi chạy Gunicorn và Nginx

Một trong những lỗi thường gặp nhất là 502 Bad Gateway. Lỗi này xảy ra khi Nginx không thể kết nối được với Gunicorn. Nguyên nhân có thể là do Gunicorn chưa được khởi động, bị treo, hoặc Nginx đang trỏ đến sai địa chỉ/cổng. Hãy kiểm tra lại xem Gunicorn có đang chạy và lắng nghe trên đúng 127.0.0.1:8000 hay không.

Lỗi 504 Gateway Timeout xuất hiện khi Gunicorn mất quá nhiều thời gian để xử lý một yêu cầu. Điều này có thể do một tác vụ nặng trong ứng dụng của bạn. Bạn có thể cần tối ưu mã nguồn hoặc tăng giá trị timeout trong cấu hình Nginx.

Lỗi về quyền truy cập (permission) cũng rất phổ biến. Người dùng chạy Nginx (thường là www-data) có thể không có quyền đọc/ghi vào các file hoặc socket của dự án. Hãy đảm bảo cấp quyền phù hợp cho thư mục dự án của bạn.

Cuối cùng, hãy kiểm tra tường lửa (firewall). Nếu bạn đang sử dụng ufw, hãy chắc chắn rằng bạn đã cho phép lưu lượng truy cập vào Nginx.
sudo ufw allow 'Nginx Full'
Lệnh này sẽ mở cả cổng 80 (HTTP) và 443 (HTTPS).

Hình minh họa

Tối ưu và bảo trì

Để ứng dụng chạy mượt mà, bạn cần tối ưu cấu hình. Điều chỉnh số lượng worker của Gunicorn là một khởi đầu tốt. Hãy thử nghiệm với các con số khác nhau để tìm ra cấu hình phù hợp nhất với tải của ứng dụng và tài nguyên máy chủ.

Bạn cũng có thể điều chỉnh giá trị timeout. Nếu ứng dụng của bạn có những tác vụ cần thời gian xử lý dài, hãy tăng giá trị --timeout của Gunicorn và proxy_read_timeout trong Nginx để tránh bị ngắt kết nối giữa chừng.

Việc giám sát dịch vụ là rất quan trọng. Sử dụng các công cụ như htop để theo dõi việc sử dụng CPU và bộ nhớ của các tiến trình Gunicorn. Ngoài ra, hãy thiết lập logrotate cho các file log của Nginx để chúng không chiếm quá nhiều dung lượng đĩa theo thời gian. Bảo trì và giám sát định kỳ sẽ giúp ứng dụng của bạn luôn hoạt động ở hiệu suất cao nhất.

Best Practices

Để xây dựng một hệ thống chuyên nghiệp và dễ bảo trì, việc tuân thủ các thực hành tốt nhất (best practices) là vô cùng cần thiết. Dưới đây là những khuyến nghị quan trọng khi triển khai Flask với Gunicorn và Nginx.

Luôn chạy ứng dụng trong môi trường ảo. Điều này giúp cô lập các gói phụ thuộc, tránh xung đột và làm cho việc quản lý dự án trở nên sạch sẽ, dễ dàng hơn rất nhiều. Mỗi dự án nên có một môi trường ảo riêng.

Hình minh họa

Sử dụng systemd để quản lý Gunicorn. Thay vì chạy Gunicorn thủ công trong terminal, hãy tạo một service unit của systemd. Điều này cho phép Gunicorn tự động khởi động cùng hệ thống và tự khởi động lại nếu bị lỗi.
Tạo file service: sudo nano /etc/systemd/system/gunicorn.service
Nội dung file:
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=your_user
Group=www-data
WorkingDirectory=/home/your_user/myproject
Environment="PATH=/home/your_user/myproject/venv/bin"
ExecStart=/home/your_user/myproject/venv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 app:app

[Install]
WantedBy=multi-user.target

Sau đó, bạn có thể quản lý Gunicorn bằng các lệnh sudo systemctl start/stop/restart/status gunicorn.

Thiết lập firewall phù hợp. Chỉ mở các cổng thực sự cần thiết. Thông thường, đó là cổng 22 (SSH), 80 (HTTP), và 443 (HTTPS). Sử dụng ufw để quản lý các quy tắc một cách đơn giản.

Không bao giờ chạy Flask với server phát triển. Máy chủ tích hợp sẵn của Flask (app.run()) chỉ dành cho mục đích phát triển. Nó không an toàn, không hiệu quả và không thể mở rộng cho môi trường sản xuất. Luôn sử dụng một máy chủ WSGI như Gunicorn.

Hình minh họa

Định kỳ kiểm tra logs và cập nhật bảo mật. Các file log của Nginx và Gunicorn chứa rất nhiều thông tin quý giá về các lỗi và các mối đe dọa bảo mật tiềm tàng. Hãy thường xuyên xem xét chúng và luôn cập nhật hệ điều hành cũng như các gói phần mềm lên phiên bản mới nhất.

Kết luận

Việc triển khai ứng dụng Flask bằng Gunicorn và Nginx là một tiêu chuẩn vàng trong ngành. Sự kết hợp này mang lại một kiến trúc mạnh mẽ, an toàn và có khả năng mở rộng cao. Gunicorn đảm bảo ứng dụng của bạn được phục vụ một cách hiệu quả, trong khi Nginx đóng vai trò là một lá chắn vững chắc, xử lý lưu lượng truy cập và tối ưu hóa hiệu suất.

Qua bài hướng dẫn này, bạn đã học được cách thiết lập một môi trường sản xuất hoàn chỉnh trên Ubuntu 20.04, từ việc chuẩn bị hệ thống, cài đặt các công cụ cần thiết, cho đến việc cấu hình và xử lý sự cố. Việc áp dụng những kiến thức này không chỉ giúp ứng dụng của bạn chạy ổn định hơn mà còn thể hiện sự chuyên nghiệp trong quá trình phát triển.

Bước tiếp theo cho bạn là gì? Hãy thử triển khai chứng chỉ SSL miễn phí với Let’s Encrypt để bảo mật trang web của mình với HTTPS, hoặc tìm hiểu cách cấu hình Nginx để phục vụ nhiều ứng dụng trên cùng một máy chủ. Chúc bạn thành công trên hành trình xây dựng và phát triển các dự án web của mình!

Hình minh họa

Đánh giá
Tác giả

Mạnh Đức

Có cao nhân từng nói rằng: "Kiến thức trên thế giới này đầy rẫy trên internet. Tôi chỉ là người lao công cần mẫn đem nó tới cho người cần mà thôi !"

Chia sẻ
Bài viết liên quan