Flask là một framework Python được sử dụng phổ biến để xây dựng các website vừa và nhỏ. Nó cung cấp nhiều công cụ đơn giản để xử lý các request web, cung cấp hàng loạt tính năng linh hoạt cho các ứng dụng web. Trong bài viết này, Vietnix sẽ hướng dẫn bạn cách chạy ứng dụng Flask với Gunicorn và Nginx trên Ubuntu 20.04, trong đó sử dụng Gunicorn làm máy chủ ứng dụng và Nginx làm reverse proxy front-end.
Yêu cầu chuẩn bị để chạy ứng dụng Flask với Gunicorn và Nginx trên Ubuntu 20.04
Để bắt đầu thực hiện theo hướng dẫn, bạn cần chuẩn bị các yêu cầu sau đây:
- Một máy chủ đã cài đặt Ubuntu 20.04, được cấu hình và quản lý thông qua user non-root với đặc quyền sudo.
- Cài đặt sẵn Nginx ở máy chủ trên để chuyển tiếp các request web.
- Một domain được cấu hình trỏ đến máy chủ của bạn và đã tạo các bản ghi DNS sau: Một bản ghi A với
your_domain
trỏ đến địa chỉ IP public máy chủ của bạn; một bản ghi A vớiwww.your_domain
trỏ đến địa chỉ IP public máy chủ của bạn. - Có hiểu biết về đặc tả WSGI mà máy chủ Gunicorn sẽ dùng để giao tiếp với ứng dụng Flask của bạn.
Hướng dẫn cách để chạy ứng dụng Flask với Gunicorn và Nginx trên Ubuntu 20.04
Để thiết lập máy chủ Gunicorn và khởi động, cấu hình Nginx hoạt động như một reverse proxy front-end, bạn thực hiện theo các bước dưới đây:
Bước 1: Cài đặt các thành phần từ Ubuntu Repositories
Đầu tiên, bạn cần cài đặt tất cả các thành phần cần thiết từ Ubuntu Repositories, bao gồm pip
, trình quản lý gói Python dùng để quản lý các thành phần Python. Bạn sẽ lấy các file phát triển Python để thiết lập một số thành phần Gunicorn.
Đầu tiên hãy cập nhật local package index và cài đặt các gói cho phép xây dựng môi trường Python. Chúng bao gồm python3-pip
cùng với một vài gói và công cụ phát triển cần thiết cho môi trường lập trình mạnh mẽ.
$ sudo apt update $ sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
Với các gói có sẵn này, bạn có thể tiến hành tạo môi trường ảo để thực hiện project của mình.
Bước 2: Tạo một môi trường ảo Python
Tiếp theo, bạn cần thiết lập một môi trường ảo để cô lập ứng dụng Flask khỏi các file Python khác trên hệ thống. Bắt đầu thao tác này bằng cách cài gói python3-venv
, sử dụng module venv
:
$ sudo apt install python3-venv
Tiếp theo, hãy tạo một thư mục cha cho Flack project, di chuyển nó vào thư mục sau đây:
$ mkdir ~/myproject $ cd ~/myproject
Tạo một môi trường ảo để lưu trữ các yêu cầu Python của Flask project bằng cách sử dụng câu lệnh:
$ python3 -m venv myprojectenv
Câu lệnh trên sẽ giúp bạn cài đặt một bản sao Python và pip
cục bộ vào một thư mục được gọi là myprojectenv
trong project của bạn.
Trước khi cài đặt các ứng dụng trong môi trường ảo, bạn cần kích hoạt nó bằng câu lệnh:
$ source myprojectenv/bin/activate
Dấu nhắc lệnh sẽ thay đổi cho biết rằng bạn đang hoạt động trong môi trường ảo, giao diện hiển thị sẽ có dạng như sau: (myprojectenv)user@host:~/myproject$
.
Bước 3: Cài đặt ứng dụng Flask
Hiện tại, mọi thao tác của bạn sẽ được thực hiện trên môi trường ảo. Bạn có thể cài đặt Flask và Gunicorn để bắt đầu thiết lập ứng dụng.
Đầu tiên, hãy cài đặt wheel
với phiên bản cục bộ của pip
để bảo đảm rằng các gói của bạn có thể cài đặt ngay cả khi thiếu bản lưu trữ:
$ pip install wheel
Lưu ý, bất kể đang sử dụng phiên bản Python nào thì khi kích hoạt môi trường ảo hóa xong bạn nên sử dụng lệnh pip
chứ không phải là pip3
.
Tiếp theo, bạn tiến hành cài đặt Gunicorn và Flask:
(myprojectenv) $ pip install gunicorn flask
Tạo một ứng dụng mẫu
Bây giờ, bạn đã có sẵn Flask để tạo một ứng dụng đơn giản. Flask là một microframework nên không bao gồm nhiều công cụ như các framework tích hợp khác. Nó tồn tại dưới dạng một module mà bạn có thể nhập vào project của mình để khởi tạo một ứng dụng web.
Bạn tiến hành tạo ứng dụng Flask trong một file duy nhất, gọi là myproject.py
:
(myprojectenv) $ nano ~/myproject/myproject.py
Mã ứng dụng sẽ được lưu trữ trong file này, cho phép nhập Flask và khởi tạo một Flask object. Bạn có thể sử dụng nó để xác định các hàm nên chạy khi một route cụ thể được yêu cầu:
from flask import Flask app = Flask(name) @app.route("/") def hello(): return "<h1 style='color:blue'>Xin chào!</h1>" if name == "main": app.run(host='0.0.0.0')
Cách làm trên đơn giản là việc xác định nội dung cần hiển thị khi truy cập vào root domain. Sau khi hoàn thành, bạn lưu và đóng file.
Bạn nên kích hoạt thêm tường lửa UFW khi thiết lập máy chủ. Để kiểm tra ứng dụng, bạn cần cho phép truy cập đến cổng 5000
:
(myprojectenv) $ sudo ufw allow 5000
Bây giờ bạn có thể kiểm tra ứng dụng Flask bằng câu lệnh sau:
(myprojectenv) $ python myproject.py
Bạn sẽ nhìn thấy output như dưới đây, bao gồm một cảnh báo nhắc nhở không nên thiết lập máy chủ trong quá trình:
Output * Serving Flask app "myproject" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
Truy cập vào địa chỉ IP trên máy chủ của bạn, kèm theo đuôi :5000
trên trình duyệt web:
http://your_server_ip:5000
Bạn sẽ thấy màn hình hiển thị nội dung tương tự như sau:
Khi hoàn thành, bạn nhấn CTRL-C
trong cửa sổ terminal để dừng máy chủ phát triển Flask.
Tạo WSGI Entry Point
Tiếp theo, bạn tạo một file với vai trò là entry point cho ứng dụng của mình. Việc này sẽ giúp máy chủ Gunicorn biết cách tương tác với ứng dụng.
Gọi file tên là wsgi.py
:
(myprojectenv) $ nano ~/myproject/wsgi.py
Trong file này, bạn nhập đối tượng Flask từ ứng dụng rồi chạy câu lệnh sau:
from myproject import app if __name__ == "__main__": app.run()
Sau khi hoàn tất, bạn nhấn lưu và đóng file.
Để quá trình thiết lập Flask diễn ra thuận lợi và không gặp bất cứ trở ngại nào, bạn cần sở hữu một máy chủ linh hoạt với toàn quyền quản trị. Trong đó, VPS Vietnix chính là giải pháp tối ưu đáp ứng những yêu cầu này. VPS Vietnix sở hữu những ưu điểm nổi trội như:
- Tốc độ truyền tải dữ liệu và độ ổn định cao giúp khách hàng có thể triển khai mọi website, ứng dụng một cách mượt mà nhất.
- Toàn quyền quản trị và có thể tự do cài đặt mọi hệ điều hành, phần mềm theo nhu cầu sử dụng. Đội ngũ kỹ thuật túc trực 24/7 sẵn sàng hỗ trợ nếu người dùng gặp khó khăn trong quá trình này.
- Tiết kiệm chi phí với nhiều gói dịch vụ theo nhiều cấu hình khác nhau, từ VPS Giá Rẻ, VPS Cao Cấp, Cloud Server, VPS NVMe cho tới VPS GPU.
Nếu bạn đang tìm kiếm một giải pháp linh hoạt, tiết kiệm chi phí và đáp ứng được những yêu cầu cao về quản trị máy chủ thì VPS Vietnix chính là lựa chọn tốt nhất dành cho bạn.
Bước 4: Cấu hình Gunicorn
Trước khi tiếp tục, bạn nên kiểm tra xem Gunicorn có thể hoạt động chính xác hay không. Để làm điều này, bạn chỉ cần truyền cho nó tên của entry point. Entry point này được xây dựng dưới dạng tên của module (loại bỏ phần mở rộng .py
), cộng với tên của callable trong ứng dụng. Đối với trường hợp này, đó là wsgi:app
.
Bạn sẽ chỉ định interface và port để ứng dụng có thể bắt đầu kết nối trên một interface có sẵn công khai:
(myprojectenv) $ cd ~/myproject (myprojectenv) $ gunicorn --bind 0.0.0.0:5000 wsgi:app
Bạn sẽ nhận được output như sau:
Output [2020-05-20 14:13:00 +0000] [46419] [INFO] Starting gunicorn 20.0.4 [2020-05-20 14:13:00 +0000] [46419] [INFO] Listening at: http://0.0.0.0:5000 (46419) [2020-05-20 14:13:00 +0000] [46419] [INFO] Using worker: sync [2020-05-20 14:13:00 +0000] [46421] [INFO] Booting worker with pid: 46421
Truy cập địa chỉ IP máy chủ của bạn với :5000
được thêm vào cuối trong trình duyệt web một lần nữa:
http://your_server_ip:5000
Bạn sẽ nhận được output của ứng dụng như sau:
Khi bạn xác nhận được Gunicorn đã hoạt động chính xác, hãy nhấn CTRL-C
trong terminal.
Sau khi đã hoàn tất môi trường ảo, bạn có thể tắt nó đi:
(myprojectenv) $ deactivate
Các câu lệnh Python bất kỳ bây giờ sẽ sử dụng lại môi trường Python của hệ thống.
Tiêp theo, bạn tạo unit file dịch vụ systemd. Việc tạo systemd unit file cho phép hệ thống tự khởi động Gunicorn và cung cấp ứng dụng Flask mỗi khi máy chủ khởi động.
Tạo một unit file kết thúc bằng .service
trong thư mục /etc/systemd/system
để bắt đầu:
$ sudo nano /etc/systemd/system/myproject.service
Ở trong đó, bạn bắt đầu với phần [Unit]
được dùng để chỉ định metadata và dependencies. Bạn cần đặt mô tả dịch vụ của mình ở đây và cho phép hệ thống chỉ khởi động khi đã đạt được networking target:
[Unit] Description=Gunicorn instance to serve myproject After=network.target
Tiếp theo, bạn mở phần [Service]
ra. Phần này sẽ chỉ định người dùng và nhóm mà bạn muốn tiến trình chạy bên dưới. Bạn hãy cấp quyền sở hữu tiến trình cho tài khoản user thông thường bởi vì nó sở hữu tất cả các file liên quan. Đồng thời bạn cũng cần cấp quyền sở hữu cho nhóm www-data
để Nginx có thể giao tiếp dễ dàng với các tiến trình Gunicorn. Lưu ý bạn cần phải thay username ở đây thành username của bạn:
[Unit] Description=Gunicorn instance to serve myproject After=network.target [Service] User=vietnix Group=www-data
Tiếp theo, bạn hãy map thư mục làm việc và thiết lập môi trường PATH
để hệ thống khởi động biết rằng các file thực thi đang đặt trong môi trường ảo. Đồng thời bạn hãy chỉ định lệnh để khởi động dịch vụ. Lệnh này sẽ thực hiện các điều sau đây:
- Bắt đầu 3 tiến trình làm việc (bạn nên điều chỉnh nó tùy vào mức độ cần thiết).
- Tạo liên kết với file Unix socket,
myproject.sock
trong thư mục dự án của bạn. Bạn cần thiết lập giá trị umask là007
để tạo tạo file socket cấp quyền cho chủ sở hữu và nhóm truy cập; đồng thời hạn chế truy cập của người dùng khác. - Chỉ định tên file WSGI entry point cùng với Python callable trong file đó (
wsgi:app
).
Systemd sẽ yêu cần bạn cung cấp đường dẫn đầy đủ đến chương trình thực thi Gunicorn được cài đặt trong môi trường ảo. Bạn nhớ thay thế thông tin username và đường dẫn project bằng thông tin của bạn:
[Unit] Description=Gunicorn instance to serve myproject After=network.target [Service] User=vietnix Group=www-data WorkingDirectory=/home/vietnix/myproject Environment="PATH=/home/vietnix/myproject/myprojectenv/bin" ExecStart=/home/vietnix/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
Cuối cùng, bạn thêm phần [Install]
, nó cho biết systemd nên liên kết dịch vụ này với cái gì khi được kích hoạt. Nếu bạn muốn dịch vụ này bắt đầu khi hệ thống đa người dùng thông thường đã hoạt động thì thực hiện như sau:
[Unit] Description=Gunicorn instance to serve myproject After=network.target [Service] User=vietnix Group=www-data WorkingDirectory=/home/vietnix/myproject Environment="PATH=/home/vietnix/myproject/myprojectenv/bin" ExecStart=/home/vietnix/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app [Install] WantedBy=multi-user.target
Như vậy, file service systemd đã hoàn tất, bạn nhấn lưu và đóng lại.
Bây giờ bạn có thể bắt đầu dịch vụ Gunicorn đã tạo và kích hoạt nó khi hệ thống khởi động:
$ sudo systemctl start myproject $ sudo systemctl enable myproject
Kiểm tra trạng thái:
$ sudo systemctl status myproject
Bạn sẽ thấy output như sau:
Output ● myproject.service - Gunicorn instance to serve myproject Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-05-20 14:15:18 UTC; 1s ago Main PID: 46430 (gunicorn) Tasks: 4 (limit: 2344) Memory: 51.3M CGroup: /system.slice/myproject.service ├─46430 /home/vietnix/myproject/myprojectenv/bin/python3 /home/vietnix/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46449 /home/vietnix/myproject/myprojectenv/bin/python3 /home/vietnix/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46450 /home/vietnix/myproject/myprojectenv/bin/python3 /home/vietnix/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app └─46451 /home/vietnix/myproject/myprojectenv/bin/python3 /home/vietnix/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
Nếu bạn thấy có bất cứ lỗi nào xảy ra, hãy giải quyết chúng trước khi thực hiện các bước tiếp theo.
Bước 5: Cấu hình Nginx để proxy request
Máy chủ ứng dụng Gunicorn hiện đang chạy và chờ request trên file socket trong thư mục project. Bây giờ bạn cần cấu hình Nginx để chuyển các web request đến socket bằng cách thêm một số chỉnh sửa nhỏ trong file cấu hình.
Đầu tiên, bạn tạo một file cấu hình server block mới trong thư mục sites-available
của Nginx. Gọi đó là myproject
để phù hợp với phần tiếp theo trong hướng dẫn này:
$ sudo nano /etc/nginx/sites-available/myproject
Mở một server block và cho Nginx lắng nghe trên cổng mặc định 80
. Đồng thời cho phép Nginx sử dụng server block cho các yêu cầu đối với tên miền của máy chủ:
server { listen 80; server_name your_domain www.your_domain; }
Tiếp theo, bạn thêm một location block phù hợp, bao gồm file proxy_params
để chỉ định một vài thông số chuyển tiếp chung cần thiết. Sau đó bạn chuyển tiếp các request đến socket đã được định nghĩa bằng cách sử dụng proxy_pass
:
server { listen 80; server_name your_domain www.your_domain; location / { include proxy_params; proxy_pass http://unix:/home/vietnix/myproject/myproject.sock; } }
Bạn lưu và đóng file sau khi hoàn tất.
Để kích hoạt cấu hình Nginx server block vừa tạo, bạn liên kết file đó với thư mục sites-enabled
:
$ sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Với file trong thư mục đó, bạn kiểm tra lỗi cú pháp bằng câu lệnh:
$ sudo nginx -t
Nếu kết quả trả về không chỉ ra bất cứ vấn đề nào, bạn hãy khởi động lại tiến trình Nginx để cập nhật cấu hình mới:
$ sudo systemctl restart nginx
Cuối cùng, bạn điều chỉnh lại cài đặt tường lửa. Lúc này bạn sẽ không cần truy cập thông qua port 5000
nên có thể bỏ thiết lập này đi. Cho phép toàn quyền truy cập vào máy chủ Nginx bằng cách thực hiện câu lệnh:
$ sudo ufw delete allow 5000 $ sudo ufw allow 'Nginx Full'
Bây giờ bạn có thể truy cập vào tên miền máy chủ bằng trình duyệt web:
http://your_domain
Bạn sẽ nhận được kết quả trên ứng dụng như sau:
Nếu bạn gặp phải bất kỳ lỗi gì, hãy kiểm tra lại những thông tin sau:
sudo less /var/log/nginx/error.log
: Kiểm tra nhật ký lỗi Nginx.sudo less /var/log/nginx/access.log
: Kiểm tra nhật ký truy cập Nginx.sudo journalctl -u nginx
: Kiểm tra nhật ký tiến trình Nginx.sudo journalctl -u myproject
: Kiểm tra nhật ký Gunicorn của ứng dụng Flask.
Bước 6: Bảo mật ứng dụng
Để bảo đảm traffic đến server luôn an toàn, bạn cần tạo chứng chỉ SSL cho tên miền. Bạn có thể lấy chứng chỉ SSL tên miền miễn phí từ Let’s Encrypt, tự tạo chứng chỉ self-signed hoặc mua chứng chỉ từ các nhà cung cấp và thực hiện cấu hình cho Nginx.
Cài đặt gói Nginx của Certbot với apt
:
$ sudo apt install python3-certbot-nginx
Certbot là một trong những phần mềm hỗ trợ cài đặt SSL Let’s Encrypt phổ biến nhất. Certbot cung cấp nhiều cách lấy chứng chỉ SSL thông qua các plugin. Plugin Nginx sẽ đảm nhận việc cấu hình Nginx và tải lại cấu hình khi cần thiết. Để sử dụng plugin này, bạn gõ lệnh:
$ sudo certbot --nginx -d your_domain -d www.your_domain
Câu lệnh trên giúp chạy certbot
với plugin --nginx
, sử dụng -d
để chỉ định các tên sẽ hợp lệ.
Nếu đây là lần đầu tiên chạy certbot
, bạn sẽ được yêu cầu nhập địa chỉ email và chấp nhận các điều khoản. Sau đó, certbot
sẽ kết nối với máy chủ Let’s Encrypt và chạy thử để xác nhận rằng bạn kiểm soát tên miền mà bạn đang yêu cầu chứng chỉ.
Nếu thành công, certbot
sẽ hỏi bạn cách cấu hình các thiết lập HTTPS của bạn:
Output Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):
Bạn lựa chọn xong nhấn ENTER
, cấu hình sẽ được cập nhật và Nginx sẽ được tải lại để áp dụng các thiết lập mới. Sau khi hoàn tất, certbot
sẽ thông báo cho bạn biết quá trình đã thành công và nơi lưu trữ chứng chỉ của bạn:
Output IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem Your cert will expire on 2020-08-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Nếu bạn đã thực hiện cài đặt Nginx theo yêu cầu ban đầu, bạn sẽ không cần cấu hình HTTP dự phòng nữa:
$ sudo ufw delete allow 'Nginx HTTP'
Để xác nhận cấu hình, bạn truy cập lại tên miền sử dụng https://
:
https://your_domain
Bạn sẽ thấy output hiển thị ứng dụng cùng với chứng nhận bảo mật đã được cài đặt vào trình duyệt.
Nếu bạn chưa sở hữu chứng chỉ SSL và muốn tìm một nhà cung cấp uy tín để mua thì Vietnix là lựa chọn tối ưu nhất cho bạn. Với hơn 10 năm kinh nghiệm hoạt động cung cấp VPS, tên miền, Vietnix đã xây dựng được uy tín và sự tin tưởng từ hàng ngàn khách hàng.
Tính tới thời điểm hiện tại, Vietnix đã cùng đồng hành với hơn 50.000 khách hàng và kích hoạt hơn 100.000 dịch vụ. Do đó, bạn có thể hoàn toàn yên tâm về chất lượng dịch vụ của Vietnix. Liên hệ với Vietnix để được tư vấn các gói dịch vụ tối ưu theo nhu cầu sử dụng của bạn:
- Địa chỉ: 265 Hồng Lạc, Phường 10, Quận Tân Bình, Thành Phố Hồ Chí Minh
- Hotline: 1800 1093 – 07 088 44444
- Email: sales@vietnix.com.vn
Lời kết
Trong hướng dẫn về cách chạy ứng dụng Flask với Gunicorn và Nginx trên Ubuntu 20.04 trên, Vietnix đã hướng dẫn bạn cách thiết lập và bảo mật ứng dụng Flask đơn giản trong môi trường ảo Python. Cùng với đó là cách tạo một server block Nginx để chuyển tiếp client traffic web đến máy chủ ứng dụng, truyền tải các external request và thiết lập bảo mật với Let’s Encrypt. Nếu gặp bất cứ khó khăn nào trong quá trình này, hãy để lại bình luận bên dưới để được hỗ trợ nhé.