文章目錄
- 說個問題
- 寫個方案
- 一、安裝Ubuntu Server
- 二、安裝Web服務器
- 采用Nginx服務器
- 三、安裝Python及依賴
- 創建項目虛擬環境
- 四、安裝Python Web框架
- 采用Flask框架
- 創建和運行Flask應用(以后的重點)
- 五、安裝WSGI服務器
- 采用Gunicorn
- 六、配置Nginx
- 七、驗證部署
- 八、擴展
- 編寫POST請求
說個問題
自己寫了一個Python小程序,傳入一定參數就有一定的輸出,現在想開放給所有人在線使用,如何搭建服務器以及如何處理用戶的請求和響應???
寫個方案
存在多種方案,作者采用的是Gunicorn配合Nginx,用戶訪問Nginx服務器,Nginx反向代理將請求傳給Gunicorn,Gunicorn調用Python應用程序,應用程序處理后將結果回傳Gunicorn,Gunicorn傳遞給Nginx,Nginx最后響應給用戶。
一、安裝Ubuntu Server
參考文章:【SH】VMware虛擬機安裝Ubuntu Server 24系統研發筆記
二、安裝Web服務器
采用Nginx服務器
在線文檔和支持:http://nginx.org/
也可以采用Apache,作者經過詳細了解和異同點比較之后選擇了Nginx,Nginx更加輕量級,資源消耗更少,靜態文件(如HTML、圖片、CSS等直接從磁盤讀取的內容)處理更加高效,配置更加簡單。而動態文件可以反向代理將動態請求轉發給后端的應用程序服務器處理(如uWSGI)。
- 更新軟件包索引,確保索引是最新的,
sudo apt update
sh@sheephero:~$ sudo apt update
[sudo] password for sh:
Hit:1 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble InRelease
Get:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates InRelease [126 kB]
Get:3 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-backports InRelease [126 kB]
Hit:4 http://security.ubuntu.com/ubuntu noble-security InRelease
Fetched 252 kB in 1s (189 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
66 packages can be upgraded. Run 'apt list --upgradable' to see them.
N: Missing Signed-By in the sources.list(5) entry for 'http://mirrors.tuna.tsinghua.edu.cn/ubuntu'
N: Missing Signed-By in the sources.list(5) entry for 'http://mirrors.tuna.tsinghua.edu.cn/ubuntu'
- 用apt包管理器安裝Nginx,
sudo apt install nginx
sh@sheephero:~$ sudo apt install nginx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:nginx-common
Suggested packages:fcgiwrap nginx-doc ssl-cert
The following NEW packages will be installed:nginx nginx-common
0 upgraded, 2 newly installed, 0 to remove and 66 not upgraded.
Need to get 552 kB of archives.
After this operation, 1,596 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates/main amd64 nginx-common all 1.24.0-2ubuntu7.1 [31.2 kB]
Get:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates/main amd64 nginx amd64 1.24.0-2ubuntu7.1 [521 kB]
Fetched 552 kB in 1s (1,071 kB/s)
Preconfiguring packages ...
Selecting previously unselected package nginx-common.
(Reading database ... 83751 files and directories currently installed.)
Preparing to unpack .../nginx-common_1.24.0-2ubuntu7.1_all.deb ...
Unpacking nginx-common (1.24.0-2ubuntu7.1) ...
Selecting previously unselected package nginx.
Preparing to unpack .../nginx_1.24.0-2ubuntu7.1_amd64.deb ...
Unpacking nginx (1.24.0-2ubuntu7.1) ...
Setting up nginx (1.24.0-2ubuntu7.1) ...
Setting up nginx-common (1.24.0-2ubuntu7.1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
Processing triggers for ufw (0.36.2-6) ...
Processing triggers for man-db (2.12.0-4build2) ...
Scanning processes...
Scanning linux images...Running kernel seems to be up-to-date.
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
- 啟動Nginx服務并檢查其狀態,啟動:
sudo systemctl start nginx
查看狀態:sudo systemctl status nginx
sh@sheephero:~$ sudo systemctl start nginx
sh@sheephero:~$ sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy serverLoaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)Active: active (running) since Mon 2024-12-16 01:06:56 UTC; 9min agoDocs: man:nginx(8)Process: 3273 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)Process: 3275 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)Main PID: 3276 (nginx)Tasks: 3 (limit: 4556)Memory: 2.4M (peak: 2.5M)CPU: 11msCGroup: /system.slice/nginx.service├─3276 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"├─3277 "nginx: worker process"└─3279 "nginx: worker process"Dec 16 01:06:56 sheephero systemd[1]: Starting nginx.service - A high performance web server and a reverse proxy server...
Dec 16 01:06:56 sheephero systemd[1]: Started nginx.service - A high performance web server and a reverse proxy server.
- 打開瀏覽器,輸入服務器的IP地址和端口(端口默認80),如果看見Nginx的歡迎界面,說明安裝成功!😀🎉
三、安裝Python及依賴
Ubuntu Server 24系統自帶Python3,查看安裝版本:python3 --version
sh@sheephero:~$ python3 --version
Python 3.12.3
但是沒有安裝venv依賴,需要安裝: apt install python3.12-venv
sh@sheephero:~$ sudo apt install python3.12-venv
[sudo] password for sh:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:python3-pip-whl python3-setuptools-whl
The following NEW packages will be installed:python3-pip-whl python3-setuptools-whl python3.12-venv
0 upgraded, 3 newly installed, 0 to remove and 66 not upgraded.
Need to get 2,424 kB of archives.
After this operation, 2,771 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates/universe amd64 python3-pip-whl all 24.0+dfsg-1ubuntu1.1 [1,703 kB]
Get:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates/universe amd64 python3-setuptools-whl all 68.1.2-2ubuntu1.1 [716 kB]
Get:3 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates/universe amd64 python3.12-venv amd64 3.12.3-1ubuntu0.3 [5,678 B]
Fetched 2,424 kB in 1s (3,600 kB/s)
Selecting previously unselected package python3-pip-whl.
(Reading database ... 83799 files and directories currently installed.)
Preparing to unpack .../python3-pip-whl_24.0+dfsg-1ubuntu1.1_all.deb ...
Unpacking python3-pip-whl (24.0+dfsg-1ubuntu1.1) ...
Selecting previously unselected package python3-setuptools-whl.
Preparing to unpack .../python3-setuptools-whl_68.1.2-2ubuntu1.1_all.deb ...
Unpacking python3-setuptools-whl (68.1.2-2ubuntu1.1) ...
Selecting previously unselected package python3.12-venv.
Preparing to unpack .../python3.12-venv_3.12.3-1ubuntu0.3_amd64.deb ...
Unpacking python3.12-venv (3.12.3-1ubuntu0.3) ...
Setting up python3-setuptools-whl (68.1.2-2ubuntu1.1) ...
Setting up python3-pip-whl (24.0+dfsg-1ubuntu1.1) ...
Setting up python3.12-venv (3.12.3-1ubuntu0.3) ...
Scanning processes...
Scanning linux images...Running kernel seems to be up-to-date.
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
安裝Python及依賴(已安裝可省略)
sudo apt install python3 python3-pip python3-venv
創建項目虛擬環境
- 選擇一個合適的目錄用于存放項目文件,并在該目錄中創建Python虛擬環境
mkdir dip_project && cd dip_project
- 為了管理項目的依賴,很有必要每個項目創建一個虛擬環境:
python3 -m venv dipenv
- 激活Python虛擬環境
source dipenv/bin/activate
激活后,終端提示符會變為(dipenv),表示當前正在使用虛擬環境。source命令是Ubuntu中bash shell的一個內置命令,用于在當前shell環境中讀取并執行某個文件中的命令。退出虛擬環境:deactivate
sh@sheephero:~/dip_project$ source dipenv/bin/activate
(dipenv) sh@sheephero:~/dip_project$
四、安裝Python Web框架
采用Flask框架
參考文檔:https://pypi.org/project/Flask/
也可以采用Django框架,作者經過詳細了解和異同點比較之后選擇了Flask,Flask更加輕量級且靈活,適合初學者和開發小型應用程序,核心功能簡單,但也可以通過擴展實現強大功能。
- 在激活的虛擬環境中,使用pip安裝Flask,
pip install flask
(dipenv) sh@sheephero:~/dip_project$ pip install Flask
Collecting FlaskDownloading flask-3.1.0-py3-none-any.whl.metadata (2.7 kB)
Collecting Werkzeug>=3.1 (from Flask)Downloading werkzeug-3.1.3-py3-none-any.whl.metadata (3.7 kB)
Collecting Jinja2>=3.1.2 (from Flask)Downloading jinja2-3.1.4-py3-none-any.whl.metadata (2.6 kB)
Collecting itsdangerous>=2.2 (from Flask)Downloading itsdangerous-2.2.0-py3-none-any.whl.metadata (1.9 kB)
Collecting click>=8.1.3 (from Flask)Downloading click-8.1.7-py3-none-any.whl.metadata (3.0 kB)
Collecting blinker>=1.9 (from Flask)Downloading blinker-1.9.0-py3-none-any.whl.metadata (1.6 kB)
Collecting MarkupSafe>=2.0 (from Jinja2>=3.1.2->Flask)Downloading MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.0 kB)
Downloading flask-3.1.0-py3-none-any.whl (102 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 103.0/103.0 kB 352.3 kB/s eta 0:00:00
Downloading blinker-1.9.0-py3-none-any.whl (8.5 kB)
Downloading click-8.1.7-py3-none-any.whl (97 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 97.9/97.9 kB 1.6 MB/s eta 0:00:00
Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Downloading jinja2-3.1.4-py3-none-any.whl (133 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 133.3/133.3 kB 2.1 MB/s eta 0:00:00
Downloading werkzeug-3.1.3-py3-none-any.whl (224 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 224.5/224.5 kB 2.8 MB/s eta 0:00:00
Downloading MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (23 kB)
Installing collected packages: MarkupSafe, itsdangerous, click, blinker, Werkzeug, Jinja2, Flask
Successfully installed Flask-3.1.0 Jinja2-3.1.4 MarkupSafe-3.0.2 Werkzeug-3.1.3 blinker-1.9.0 click-8.1.7 itsdangerous-2.2.0
(dipenv) sh@sheephero:~/dip_project$
- 驗證安裝:
python -m flask --version
如果安裝成功,會顯示Flask的版本信息
(dipenv) sh@sheephero:~/dip_project$ python -m flask --version
Python 3.12.3
Flask 3.1.0
Werkzeug 3.1.3
創建和運行Flask應用(以后的重點)
- 創建和運行Flask應用,在項目目錄里面新建一個【app.py】文件
vim app.py
,寫入如下內容(IP地址就是Ubuntu的地址):
# save this as app.py
from flask import Flaskapp = Flask(__name__)@app.route("/")
def hello():return "Hello, World!"if __name__ == '__main__':app.run(host='172.16.37.37', port=5000)
保存后,運行如下命令:python app.py
,使之處于監聽狀態。
(dipenv) sh@sheephero:~/dip_project$ python app.py* Serving Flask app 'app'* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.* Running on http://172.16.37.37:5000
Press CTRL+C to quit
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.警告:這是一個開發服務器。不要用于生產環境。請使用生產WSGI服務器代替。
- 打開客戶機的瀏覽器,訪問虛擬機的服務器,在瀏覽器中輸入
http://172.16.37.37:5000
來查看Flask應用的輸出
五、安裝WSGI服務器
WSGI服務器,用于Web服務器反向代理Python程序。
uWSGI和Gunicorn都是Web服務器,實現了WSGI(Web Server Gateway Interface)協議,用于接收請求并分發給后端應用(如Django或Flask)。
采用Gunicorn
也可以安裝uWSGI,作者經過詳細了解和異同點比較之后選擇了Gunicorn,Gunicorn配置相對簡單,易于上手。它遵循“Keep it simple and stupid”(KISS)的設計理念,提供了一個穩定且易于維護的Web服務器環境。
- 在項目虛擬環境中安裝gunicorn,
(dipenv) sh@sheephero:~/dip_project$ pip install gunicorn
Collecting gunicornDownloading gunicorn-23.0.0-py3-none-any.whl.metadata (4.4 kB)
Collecting packaging (from gunicorn)Downloading packaging-24.2-py3-none-any.whl.metadata (3.2 kB)
Downloading gunicorn-23.0.0-py3-none-any.whl (85 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 85.0/85.0 kB 305.7 kB/s eta 0:00:00
Downloading packaging-24.2-py3-none-any.whl (65 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.5/65.5 kB 1.2 MB/s eta 0:00:00
Installing collected packages: packaging, gunicorn
Successfully installed gunicorn-23.0.0 packaging-24.2
- 重新使用Gunicorn運行Flask應用(假設Flask應用名為app.py,且應用實例名為app),根據上文編寫的app.py文件來輸入命令
gunicorn --workers 4 --bind 0.0.0.0:6758 app:app
,這條命令會啟動Gunicorn,并監聽所有網絡接口上的6758端口。
【–workers 4】這個選項指定了Gunicorn應該啟動的工作進程數量。在這個例子中,它被設置為4。工作進程是實際處理請求的Python進程。增加工作進程的數量可以提高你的應用處理并發請求的能力,但是也會增加內存和CPU的使用。
【–bind 0.0.0.0:6758】這個選項告訴Gunicorn監聽哪個IP地址和端口上的連接。0.0.0.0是一個特殊的IP地址,表示監聽所有可用的網絡接口。這意味著,如果你的服務器有多個IP地址(例如,一個內網地址和一個外網地址),你的應用將能夠在所有這些地址上接受連接。6758是端口號,是應用將監聽以接受連接的TCP端口。
【app:app】這部分指定了要運行的WSGI應用。它通常遵循模塊名:應用對象名的格式。在這個例子中,app是Python模塊的名字,而第二個app是該模塊中定義的WSGI應用對象的名字。這意味著你的應用應該有一個名為app.py的文件,里面有一個名為app的Flask(或其他WSGI兼容框架)應用實例。
(dipenv) sh@sheephero:~/dip_project$ gunicorn --workers 4 --bind 0.0.0.0:6758 app:app
[2024-12-16 13:28:27 +0000] [25695] [INFO] Starting gunicorn 23.0.0
[2024-12-16 13:28:27 +0000] [25695] [INFO] Listening at: http://0.0.0.0:8000 (25695)
[2024-12-16 13:28:27 +0000] [25695] [INFO] Using worker: sync
[2024-12-16 13:28:27 +0000] [25696] [INFO] Booting worker with pid: 25696
[2024-12-16 13:28:27 +0000] [25697] [INFO] Booting worker with pid: 25697
[2024-12-16 13:28:27 +0000] [25698] [INFO] Booting worker with pid: 25698
[2024-12-16 13:28:28 +0000] [25699] [INFO] Booting worker with pid: 25699
六、配置Nginx
配置Nginx以轉發請求給Gunicorn
- 備份Nginx的默認配置文件:
(dipenv) sh@sheephero:/etc/nginx/sites-available$ sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
(dipenv) sh@sheephero:/etc/nginx/sites-available$ tree -L 3
.
├── default
└── default.bak
1 directory, 2 files
- 編輯Nginx的配置文件:
sudo vim /etc/nginx/sites-available/default
- 在配置文件中添加或修改以下內容,以將請求轉發給Gunicorn,your_server_ip_or_domain替換為你的服務器IP地址或域名:
server {listen 80;server_name your_server_ip_or_domain;location / {proxy_pass http://127.0.0.1:6758;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;}
}
- 測試Nginx配置文件的正確性:
sudo nginx -t
(dipenv) sh@sheephero:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
- 重啟Nginx服務以應用更改:
sudo systemctl restart nginx
七、驗證部署
啟動Gunicorn保持監聽,啟動Nginx服務,然后通過瀏覽器輸入http://172.16.37.37
訪問服務:
八、擴展
編寫POST請求
請看下一篇文章:【SH】Ubuntu Server 24搭建Web服務器訪問Python程序研發筆記