Giới thiệu
Trong hướng dẫn này, bạn sẽ xây dựng một ứng dụng Python bằng cách sử dụng vi khung Flask trên Ubuntu 18.04. Phần lớn bài viết này sẽ nói về cách thiết lập máy chủ ứng dụng Gunicorn cũng như cách khởi chạy ứng dụng và định cấu hình Nginx để hoạt động như một proxy ngược phía trước.
Điều kiện tiên quyết
Để hoàn thành hướng dẫn này, bạn sẽ cần:
- Máy chủ đã cài đặt Ubuntu 18.04, người dùng không phải root có đặc quyền sudo và đã bật tường lửa. Làm theo hướng dẫn thiết lập máy chủ ban đầu của chúng tôi để được hướng dẫn.
- Nginx đã được cài đặt, đang theo dõi Bước 1 và 2 về Cách cài đặt Nginx trên Ubuntu 18.04.
-
Tên miền được định cấu hình để trỏ đến máy chủ của bạn. Bạn có thể mua một cái trên Namecheap hoặc nhận một cái miễn phí trên Freenom. Bạn có thể tìm hiểu cách trỏ miền đến DigitalOcean bằng cách làm theo tài liệu liên quan về miền và DNS. Đảm bảo tạo các bản ghi DNS sau:
- Một kỷ lục A với
your_domain
trỏ đến địa chỉ IP công cộng của máy chủ của bạn. - Một kỷ lục A với
www.your_domain
trỏ đến địa chỉ IP công cộng của máy chủ của bạn.
- Một kỷ lục A với
-
Quen thuộc với đặc tả WSGI mà máy chủ Gunicorn sẽ sử dụng để giao tiếp với ứng dụng Flask của bạn. Cuộc thảo luận này bao gồm WSGI chi tiết hơn.
Bước 1 – Cài đặt các thành phần từ kho lưu trữ Ubuntu
Bước đầu tiên là cài đặt tất cả các gói cần thiết từ kho lưu trữ mặc định của Ubuntu. Điêu nay bao gôm pip
, trình quản lý gói Python, sẽ quản lý các thành phần Python của bạn. Bạn cũng sẽ nhận được các tệp phát triển Python cần thiết để xây dựng một số thành phần Gunicorn.
Đầu tiên, hãy cập nhật gói cục bộ:
Then install the packages that will allow you to build your Python environment. These include python3-pip
, cùng với một số gói và công cụ phát triển khác cần thiết cho một môi trường lập trình mạnh mẽ:
- sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
Với các gói này, hãy chuyển sang tạo môi trường ảo cho dự án của bạn.
Bước 2 - Tạo môi trường ảo Python
Tiếp theo, thiết lập một môi trường ảo để cô lập ứng dụng Flask của bạn với các tệp Python khác trên hệ thống.
Bắt đầu bằng cách cài đặt python3-venv
gói, sẽ cài đặt venv
mô-đun:
- sudo apt install python3-venv
Tiếp theo, tạo một thư mục mẹ cho dự án Flask của bạn:
Then change into the directory after you create it:
Create a virtual environment to store your Flask project's Python requirements by entering the following:
- python3.6 -m venv myprojectenv
Điều này sẽ cài đặt một bản sao cục bộ của Python và pip
vào một thư mục có tên myprojectenv
trong thư mục dự án 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ách chạy như sau:
- source myprojectenv/bin/activate
Lời nhắc của bạn sẽ thay đổi để cho biết rằng bạn hiện đang hoạt động trong môi trường ảo. Nó sẽ đọc như sau:
(myprojectenv)ssammy@host:~/myproject$
Bước 3 - Thiết lập ứng dụng bình
Bây giờ bạn đang ở trong môi trường ảo của mình, bạn có thể cài đặt Flask và Gunicorn và bắt đầu thiết kế ứng dụng của mình.
Đầu tiên, hãy cài đặt wheel
với phiên bản địa phương của pip
để đảm bảo rằng các gói của bạn sẽ cài đặt ngay cả khi chúng bị thiếu kho lưu trữ bánh xe:
Note: Regardless of which version of Python you are using, when the virtual environment is activated, you should use the pip
lệnh (không phải pip3
).
Tiếp theo, cài đặt Flask và Gunicorn:
- pip install gunicorn flask
Bây giờ bạn đã có sẵn Flask, bạn có thể tạo một ứng dụng cơ bản trong bước tiếp theo.
Tạo một ứng dụng mẫu
Vì Flask là một microframework, nó không bao gồm nhiều công cụ mà các framework đầy đủ tính năng hơn có thể có. Flask chủ yếu tồn tại dưới dạng mô-đun mà bạn có thể nhập vào các dự án của mình để hỗ trợ khởi tạo ứng dụng web.
Mặc dù ứng dụng của bạn có thể phức tạp hơn, nhưng chúng tôi sẽ tạo ứng dụng Flask của mình trong một tệp duy nhất, được gọi là myproject.py
. Tạo tệp này bằng trình soạn thảo văn bản ưa thích của bạn; ở đây chúng tôi sẽ sử dụng nano
:
- nano ~/myproject/myproject.py
Mã ứng dụng sẽ nằm trong tệp này. Nó sẽ nhập Flask và khởi tạo một đối tượng Flask. Bạn có thể sử dụng điều này để xác định các chức năng sẽ được chạy khi một tuyến đường cụ thể được yêu cầu:
~ / myproject / myproject.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello There!
"
if __name__ == "__main__":
app.run(host="0.0.0.0")
Điều này xác định nội dung sẽ hiển thị khi miền gốc được truy cập. Lưu và đóng tệp khi bạn hoàn tất. Nếu bạn đang sử dụng nano, bạn có thể thực hiện việc này bằng cách nhấn CTRL + X
sau đó Y
và ENTER
.
Nếu bạn đã làm theo hướng dẫn thiết lập máy chủ ban đầu trong điều kiện tiên quyết, bạn nên bật tường lửa UFW. Để kiểm tra ứng dụng, trước tiên bạn cần cho phép truy cập vào cổng 5000
:
Then you can test your Flask application by running the following:
You will receive output like the following, including a helpful warning reminding you not to use this server setup in production:
Output
* Serving Flask app 'myproject' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://your_server_ip:5000/ (Press CTRL+C to quit)
Truy cập địa chỉ IP của máy chủ của bạn, sau đó là :5000
trong trình duyệt web của bạn:
http://your_server_ip:5000
Bạn sẽ nhận được một cái gì đó như sau:
Khi bạn hoàn thành, hãy nhấn CTRL + C
trong cửa sổ đầu cuối của bạn để dừng máy chủ phát triển Flask.
Tạo điểm vào WSGI
Tiếp theo, tạo một tệp sẽ đóng vai trò là điểm nhập cho ứng dụng của bạn. Điều này sẽ cho máy chủ Gunicorn của bạn biết cách tương tác với ứng dụng.
Tạo một tệp mới bằng cách sử dụng trình soạn thảo văn bản ưa thích của bạn và đặt tên cho tệp đó. Ở đây, chúng tôi sẽ gọi tệp wsgi.py
:
In this file, import the Flask instance from your application and then run it:
~/myproject/wsgi.py
from myproject import app
if __name__ == "__main__":
app.run()
Lưu và đóng tệp khi bạn hoàn tất.
Bước 4 - Định cấu hình Gunicorn
Ứng dụng của bạn hiện đã được viết với một điểm nhập được thiết lập và bạn có thể tiến hành cấu hình Gunicorn.
Nhưng trước tiên, hãy chuyển sang thư mục thích hợp:
Next, you can check that Gunicorn can serve the application correctly by passing it the name of your entry point. This is constructed as the name of the module (minus the .py
phần mở rộng), cộng với tên của ứng dụng có thể gọi được. Trong trường hợp của chúng tôi, điều này được viết là wsgi:app
.
Bạn cũng sẽ chỉ định giao diện và cổng để liên kết để ứng dụng sẽ được khởi động trên giao diện có sẵn công khai:
- gunicorn --bind 0.0.0.0:5000 wsgi:app
Bạn sẽ nhận được đầu ra như sau:
Output
[2021-11-19 23:07:57 +0000] [8760] [INFO] Starting gunicorn 20.1.0
[2021-11-19 23:07:57 +0000] [8760] [INFO] Listening at: http://0.0.0.0:5000 (8760)
[2021-11-19 23:07:57 +0000] [8760] [INFO] Using worker: sync
[2021-11-19 23:07:57 +0000] [8763] [INFO] Booting worker with pid: 8763
[2021-11-19 23:08:11 +0000] [8760] [INFO] Handling signal: int
[2021-11-19 23:08:11 +0000] [8760] [INFO] Shutting down: Master
Truy cập địa chỉ IP của máy chủ của bạn với :5000
được nối lại vào cuối trong trình duyệt web của bạn:
http://your_server_ip:5000
Đầu ra của ứng dụng của bạn sẽ tạo ra những thứ sau:
Khi bạn đã xác nhận rằng nó hoạt động bình thường, hãy nhấn CTRL + C
trong cửa sổ đầu cuối của bạn.
Vì bây giờ bạn đã hoàn tất với môi trường ảo của mình, hãy hủy kích hoạt nó:
Any Python commands will now use the system's Python environment again.
Next, create the systemd service unit file. Creating a systemd unit file will allow Ubuntu's init system to automatically start Gunicorn and serve the Flask application whenever the server boots.
Create a unit file ending in .service
trong /etc/systemd/system
thư mục để bắt đầu:
- sudo nano /etc/systemd/system/myproject.service
Bên trong, hãy bắt đầu với [Unit]
, được sử dụng để chỉ định siêu dữ liệu và phần phụ thuộc. Thêm mô tả về dịch vụ của bạn tại đây và yêu cầu hệ thống init chỉ bắt đầu điều này sau khi đã đạt được mục tiêu mạng:
/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
Tiếp theo, tạo một [Service]
tiết diện. Điều này sẽ chỉ định người dùng và nhóm mà bạn muốn quá trình chạy dưới đó. Cung cấp quyền sở hữu tài khoản người dùng thông thường của bạn đối với quy trình vì nó sở hữu tất cả các tệp có liên quan. Ngoài ra, hãy cấp quyền sở hữu nhóm cho www-data nhóm để Nginx có thể giao tiếp với các quy trình Gunicorn. Hãy nhớ thay thế tên người dùng ở đây bằng tên người dùng của bạn:
/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
Tiếp theo, vạch ra thư mục làm việc và thiết lập PATH
biến môi trường để hệ thống init biết rằng các tệp thực thi cho quy trình nằm trong môi trường ảo của bạn. Ngoài ra, chỉ định lệnh để bắt đầu dịch vụ. Lệnh này sẽ thực hiện những việc sau:
- Bắt đầu 3 quy trình công nhân (mặc dù bạn nên điều chỉnh điều này nếu cần)
- Tạo và liên kết với tệp ổ cắm Unix,
myproject.sock
, trong thư mục dự án của bạn. - Đặt giá trị umask của
007
để tệp socket được tạo để cấp quyền truy cập cho chủ sở hữu và nhóm, đồng thời hạn chế quyền truy cập khác - Chỉ định tên tệp điểm nhập WSGI, cùng với Python có thể gọi trong tệp đó (
wsgi:app
)
Systemd yêu cầu bạn cung cấp đường dẫn đầy đủ đến tệp thi hành Gunicorn, tệp này được cài đặt trong môi trường ảo của bạn.
Hãy nhớ thay thế tên người dùng và đường dẫn dự án bằng thông tin của riêng bạn:
/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
Cuối cùng, thêm một [Install]
tiết diện. Thao tác này sẽ cho systemd biết phải liên kết dịch vụ này với cái gì nếu bạn cho phép nó khởi động khi khởi động. Bạn muốn dịch vụ này bắt đầu khi hệ thống nhiều người dùng thông thường đang hoạt động:
/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
Sau đó, tệp dịch vụ systemd của bạn đã hoàn tất. Lưu và đóng nó ngay bây giờ.
Bây giờ hãy bắt đầu dịch vụ Gunicorn mà bạn đã tạo:
- sudo systemctl start myproject
Sau đó, kích hoạt nó để nó bắt đầu khi khởi động:
- sudo systemctl enable myproject
Kiểm tra trạng thái:
- sudo systemctl status myproject
Bạn sẽ nhận được đầu ra như sau:
Output
● myproject.service - Gunicorn instance to serve myproject
Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset
Active: active (running) since Fri 2021-11-19 23:08:44 UTC; 6s ago
Main PID: 8770 (gunicorn)
Tasks: 4 (limit: 1151)
CGroup: /system.slice/myproject.service
├─9291 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
├─9309 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
├─9310 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
└─9311 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
…
Nếu bạn nhận được bất kỳ lỗi nào, hãy đảm bảo giải quyết chúng trước khi tiếp tục với hướng dẫn.
Bước 5 - Định cấu hình Nginx theo yêu cầu proxy
Máy chủ ứng dụng Gunicorn của bạn bây giờ sẽ được thiết lập và đang chạy, đang chờ các yêu cầu trên tệp socket trong thư mục dự án. Tiếp theo, định cấu hình Nginx để chuyển các yêu cầu web đến socket đó bằng cách thực hiện một số bổ sung nhỏ vào tệp cấu hình của nó.
Bắt đầu bằng cách tạo tệp cấu hình khối máy chủ mới trong Nginx's sites-available
danh mục. Chúng tôi sẽ gọi cái này myproject
để luôn nhất quán với phần còn lại của hướng dẫn:
- sudo nano /etc/nginx/sites-available/myproject
Mở khối máy chủ và yêu cầu Nginx lắng nghe trên cổng mặc định 80
. Ngoài ra, hãy yêu cầu nó sử dụng khối này cho các yêu cầu đối với tên miền máy chủ của bạn:
/ etc / nginx / sites-available / myproject
server {
listen 80;
server_name your_domain www.your_domain;
}
Tiếp theo, thêm một khối vị trí phù hợp với mọi yêu cầu. Trong khối này, hãy bao gồm proxy_params
tệp chỉ định một số thông số ủy quyền chung cần được đặt. Sau đó, chuyển các yêu cầu đến ổ cắm mà bạn đã xác định bằng cách sử dụng proxy_pass
chỉ thị:
/ etc / nginx / sites-available / myproject
server {
listen 80;
server_name your_domain www.your_domain;
location / {
include proxy_params;
proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
}
}
Lưu và đóng tệp khi bạn hoàn tất.
Để bật cấu hình khối máy chủ Nginx mà bạn đã tạo, hãy liên kết tệp với sites-enabled
danh mục. Bạn có thể làm điều này bằng cách chạy ln
lệnh và -s
cờ để tạo một biểu tượng hoặc Dịu dàng liên kết, trái ngược với một liên kết cứng:
- sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Với liên kết trong thư mục đó, bạn có thể kiểm tra lỗi cú pháp:
If this returns without indicating any issues, restart the Nginx process to read the new configuration:
- sudo systemctl restart nginx
Cuối cùng, điều chỉnh lại tường lửa. Vì bạn không cần truy cập thông qua cổng nữa 5000
, loại bỏ quy tắc đó:
- sudo ufw delete allow 5000
Sau đó, cho phép toàn quyền truy cập vào máy chủ Nginx:
- sudo ufw allow 'Nginx Full'
Bây giờ bạn có thể điều hướng đến tên miền của máy chủ trong trình duyệt web của bạn:
http://your_domain
Đầu ra ứng dụng của bạn sẽ xuất hiện trong trình duyệt của bạn:
Nếu bạn gặp bất kỳ lỗi nào, hãy thử kiểm tra như 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ý quy trình Nginx.sudo journalctl -u myproject
: kiểm tra nhật ký Gunicorn của ứng dụng Flask của bạn.
Bước 6 - Bảo mật ứng dụng
Để đảm bảo rằng lưu lượng truy cập vào máy chủ của bạn vẫn an toàn, bạn nên nhận chứng chỉ SSL cho miền của mình. Có nhiều cách để thực hiện việc này, bao gồm nhận chứng chỉ miễn phí từ let's encrypt, tạo chứng chỉ tự ký hoặc mua chứng chỉ từ nhà cung cấp khác và định cấu hình Nginx để sử dụng chứng chỉ đó bằng cách làm theo các bước từ 2 đến 6 của Cách tạo chứng chỉ tự ký Chứng chỉ SSL cho Nginx trong Ubuntu 18.04. Chúng tôi sẽ đi với tùy chọn một vì lợi ích hiệu quả.
Đầu tiên, hãy cài đặt Certbot bằng snap
:
- sudo snap install --classic certbot
Đầu ra của bạn sẽ hiển thị phiên bản Certbot hiện tại và cho biết cài đặt thành công:
Output
certbot 1.21.0 from Certbot Project (certbot-eff✓) installed
Tiếp theo, tạo một liên kết tượng trưng đến phần mềm mới được cài đặt /snap/bin/certbot
thực thi từ /usr/bin/
danh mục. Điều này sẽ đảm bảo rằng certbot
lệnh có thể chạy chính xác trên máy chủ của bạn:
- sudo ln -s /snap/bin/certbot /usr/bin/certbot
Certbot cung cấp nhiều cách khác nhau để lấy chứng chỉ SSL thông qua các plugin. Plugin Nginx sẽ đảm nhiệm việc định cấu hình lại Nginx và tải lại cấu hình bất cứ khi nào cần thiết. Để sử dụng plugin này, hãy nhập như sau:
- sudo certbot --nginx -d your_domain -d www.your_domain
Điều này chạy certbot
với --nginx
plugin, sử dụng -d
để chỉ định những tên bạn muốn chứng chỉ hợp lệ.
Nếu đây là lần đầu tiên bạn chạy certbot
, bạn sẽ được nhắc nhập địa chỉ email và đồng ý với các điều khoản dịch vụ. Sau khi làm như vậy, certbot
sẽ giao tiếp với máy chủ Let's Encrypt để yêu cầu chứng chỉ cho miền của bạn. Nếu thành công, bạn sẽ nhận được kết quả sau:
Output
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/jeanellehorcasitasphd.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/jeanellehorcasitasphd.com/privkey.pem
This certificate expires on 2022-03-03.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Deploying certificate
Successfully deployed certificate foryour_domain to /etc/nginx/sites-enabled/myproject
Successfully deployed certificate for your_domain to /etc/nginx/sites-enabled/myproject
Congratulations! You have successfully enabled HTTPS on https://your_domain and https://your_domain
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 đã làm theo hướng dẫn cài đặt Nginx trong điều kiện tiên quyết, bạn sẽ không cần phụ cấp hồ sơ HTTP dự phòng nữa:
- sudo ufw delete allow 'Nginx HTTP'
Để xác minh cấu hình, hãy điều hướng một lần nữa đến miền của bạn, sử dụng https://
:
https://your_domain
Bạn sẽ nhận được đầu ra ứng dụng của mình một lần nữa, cùng với chỉ báo bảo mật của trình duyệt, chỉ báo này sẽ cho biết rằng trang web đã được bảo mật.
Sự kết luận
Trong hướng dẫn này, bạn đã tạo và bảo mật một ứng dụng Flask cơ bản trong môi trường ảo Python. Bạn đã tạo một điểm vào WSGI để bất kỳ máy chủ ứng dụng hỗ trợ WSGI nào có thể giao tiếp với nó, sau đó định cấu hình máy chủ ứng dụng Gunicorn để cung cấp chức năng này. Sau đó, bạn đã tạo một tệp dịch vụ systemd để tự động khởi chạy máy chủ ứng dụng khi khởi động. Bạn cũng đã tạo một khối máy chủ Nginx chuyển lưu lượng máy khách web đến máy chủ ứng dụng để chuyển tiếp các yêu cầu bên ngoài và lưu lượng truy cập an toàn đến máy chủ của bạn bằng Let's Encrypt.
Flask là một khuôn khổ cực kỳ linh hoạt nhằm cung cấp cho các ứng dụng của bạn chức năng mà không quá hạn chế về cấu trúc và thiết kế. Bạn có thể sử dụng ngăn xếp chung được mô tả trong hướng dẫn này để phục vụ các ứng dụng bình mà bạn thiết kế.
.