ubuntu+flask+uwsgi+nginx+mysql從零部署
- ubuntu+flask+uwsgi+nginx+mysql從零部署
- 1 前言
- 2 流程概述
- 3 部署程序
- 3.0 一些說明
- 3.1 搭建Python環境
- 3.1.1 升級ubuntu系統自帶Python版本(非必要)
- 3.1.2 安裝virtualenv虛擬環境
- 3.2 測驗flask運行情況
- 3.2.1 設定騰訊云服務器安全組
- 3.2.2 服務器終端內設定防火墻
- 3.3 安裝與配置uwsgi
- 3.3.1 安裝uwsgi
- 3.3.2 配置與測驗uwsgi與flask連通
- 3.3.3 關閉uwsgi的命令
- 3.4 安裝與配置nginx
- 3.4.1 安裝nginx
- 3.4.2 配置nginx與測驗flask+uwsgi+nginx連通性
- 3.5 https相關配置
- 3.5.1 SSL證書安裝部署
- 3.5.2 修改nginx組態檔
- 3.6 安裝與配置mysql資料庫
- 4 部署程序中的一些感想
ubuntu+flask+uwsgi+nginx+mysql從零部署
1 前言
最近做的一個專案需要將原先服務器上部署好的環境重新搭建在新的服務器上,專案采用的是flask+uwsgi+nginx架構,在網上搜集資料踩坑無數,整整花了三天時間才把環境部署成功(前后一共部署了兩次,兩次都成功了),我發現網上的部署教程絕大部分無法按照他給出的步驟最終實作成功部署,總會有步驟的遺漏導致中途要更換大量的教程,前前后后花費很多時間,而且,很多教程假定開發者在部署程序沒有遇到任何報錯,事實上,我在第二次部署的程序中,按照一模一樣的步驟進行仍然遇到了第一次部署中沒有出現的報錯,因此,本文會盡可能給出詳細的版本資訊以及可能出現的問題解決,也請大家在遇到我沒有提及的報錯時,可以在評論區及時提醒我補全解決策略,
本文不涉及原理的解釋,僅從如何部署成功的角度來進行說明,因此,如若讀者想知道這樣配置背后的原理,可以在CSDN查找其他的相關博文,
2 流程概述
因為本文產生的背景是將一臺服務器已搭建好的環境遷移到另一臺服務器上,因此會有部分內容與flask+uwsgi+nginx+mysql部署不直接相關,包括資料庫檔案遷移等等,讀者根據自身專案需要取用本文方法,
- 搭建Python環境
- 測驗flask運行情況
- 安裝與配置uwsgi
- 安裝與配置nginx
- https相關配置
- 安裝與配置mysql資料庫
3 部署程序
3.0 一些說明
- 本文中假設服務器的公網ip地址為6.6.6.6,內網ip地址為2.2.2.2
- 本文專案目錄地址為/home/ubuntu
- ubuntu版本為Ubuntu 18.04.4 LTS
- 在騰訊云服務器上成功部署
3.1 搭建Python環境
搭建Python環境包含兩部分內容,一部分是ubuntu系統自身python版本的配置,一部分是uwsgi使用python版本的配置,
3.1.1 升級ubuntu系統自帶Python版本(非必要)
ubuntu@VM-0-6-ubuntu:/$ python -V
Python 2.7.17
ubuntu@VM-0-6-ubuntu:/$ python3 -V
Python 3.6.9
ubuntu系統自帶了Python2.7和Python3.6,我所開發的專案需要用的Python版本為3.7,因此我參考了下述鏈接中給出的方法進行了Python3.7的安裝與配置:
How to upgrade to python 3.7 on Ubuntu 18.10
騰訊云服務器實際運行如下:
ubuntu@VM-0-6-ubuntu:/$ sudo apt-get install python3.7
ubuntu@VM-0-6-ubuntu:/$ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1
update-alternatives: using /usr/bin/python3.6 to provide /usr/bin/python3 (python3) in auto mode
ubuntu@VM-0-6-ubuntu:/$ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 2
update-alternatives: using /usr/bin/python3.7 to provide /usr/bin/python3 (python3) in auto mode
ubuntu@VM-0-6-ubuntu:/$ sudo update-alternatives --config python3
There are 2 choices for the alternative python3 (providing /usr/bin/python3).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/python3.7 2 auto mode
1 /usr/bin/python3.6 1 manual mode
2 /usr/bin/python3.7 2 manual mode
Press <enter> to keep the current choice[*], or type selection number:
ubuntu@VM-0-6-ubuntu:/$ python3 -V
Python 3.7.5
ubuntu@VM-0-6-ubuntu:/$ pip3 -V
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.7)
至此python3.7安裝與配置完成,在控制臺查看python3版本,默認指向python3.7,且pip3指向的安裝地址也是python3.7,我之前參考過各類安裝其他版本python的教程,鏈接給出的教程是最簡單最方便的,推薦大家更換python版本時使用上述方法,
3.1.2 安裝virtualenv虛擬環境
我們上述安裝的python3.7是ubuntu系統現在默認使用的python3版本,而之后配置uwsgi時,我們可以指定uwsgi啟動的python路徑,(我的個人理解)但這個路徑只能是python虛擬環境,因此我們要在服務器里安裝virtualenv虛擬環境,參考的鏈接如下:
ubuntu 上用virtualenv安裝python不同版本的開發環境
騰訊云服務器實際運行如下:
ubuntu@VM-0-6-ubuntu:/$ sudo apt-get install python-virtualenv
這里要注意,我們要安裝的虛擬環境同樣是python3.7版本,而且虛擬環境安裝指令會將虛擬環境安裝在當前目錄下,因此我們可以新建一個目錄專門用來存放各個不同的虛擬環境,方便我們開發其他專案時使用;也可以將虛擬環境安裝在專案目錄下,此處我選擇新建一個目錄專門存放各種虛擬環境,
ubuntu@VM-0-6-ubuntu:~$ mkdir env
ubuntu@VM-0-6-ubuntu:~$ ls
env
ubuntu@VM-0-6-ubuntu:~$ cd env
ubuntu@VM-0-6-ubuntu:~/env$ ls
ubuntu@VM-0-6-ubuntu:~/env$
進入到env目錄后,我們用virtualenv命令新建一個python3.7的虛擬環境:
ubuntu@VM-0-6-ubuntu:~/env$ virtualenv -p /usr/bin/python3.7 py37env
Running virtualenv with interpreter /usr/bin/python3.7
Using base prefix '/usr'
/usr/lib/python3/dist-packages/virtualenv.py:1086: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
New python executable in /home/ubuntu/env/py37env/bin/python3.7
Also creating executable in /home/ubuntu/env/py37env/bin/python
Please make sure you remove any previous custom paths from your /home/ubuntu/.pydistutils.cfg file.
Installing setuptools, pkg_resources, pip, wheel...done.
ubuntu@VM-0-6-ubuntu:~/env$ ls
py37env
如果啟用虛擬環境,我們會看到命令列前面會多一個括號出來,括號里是我們的虛擬環境名稱,當前為未啟用狀態,現在我們將虛擬環境啟動:
ubuntu@VM-0-6-ubuntu:~/env$ source py37env/bin/activate
(py37env) ubuntu@VM-0-6-ubuntu:~/env$ python -V
Python 3.7.5
(py37env) ubuntu@VM-0-6-ubuntu:~/env$ python3 -V
Python 3.7.5
(py37env) ubuntu@VM-0-6-ubuntu:~/env$ pip -V
pip 21.3.1 from /home/ubuntu/env/py37env/lib/python3.7/site-packages/pip (python 3.7)
(py37env) ubuntu@VM-0-6-ubuntu:~/env$ pip3 -V
pip 21.3.1 from /home/ubuntu/env/py37env/lib/python3.7/site-packages/pip (python 3.7)
此時python和python3都指向python3.7,pip和pip3均屬于python3.7,虛擬環境配置成功,
3.2 測驗flask運行情況
我們在/home/ubuntu目錄下新建一個test目錄,用于后續flask、uwsgi以及nginx的測驗,進入test目錄,并在test目錄下新建一個run.py檔案,撰寫最簡單的flask代碼,進行flask運行情況測驗:
(py37env) ubuntu@VM-0-6-ubuntu:~$ mkdir test
(py37env) ubuntu@VM-0-6-ubuntu:~$ ls
env test
(py37env) ubuntu@VM-0-6-ubuntu:~$ cd test
(py37env) ubuntu@VM-0-6-ubuntu:~/test$ vim run.py
簡單的flask代碼如下:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'hello world'
if __name__ == '__main__':
app.run('0.0.0.0')
控制臺當前處于虛擬環境下,安裝flask包后,運行run.py:
(py37env) ubuntu@VM-0-6-ubuntu:~/test$ pip3 install flask
(py37env) ubuntu@VM-0-6-ubuntu:~/test$ python3 run.py
* Serving Flask app 'run' (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://2.2.2.2:5000/ (Press CTRL+C to quit)
此時打開瀏覽器,輸入公網ip地址和埠號6.6.6.6:5000應該會顯示hello world:

這里可能訪問之后無法顯示hello world或無法建立連接,那么有兩個地方需要注意(其他教程大多只會修改第一部分,而忽略了第二部分):
3.2.1 設定騰訊云服務器安全組
設定騰訊云服務器的安全組,如下圖所示位置:


我在這里圖方便,就設定了開放全部埠,當然,僅就這次配置任務而言,開放22、80、443、5000、3306等埠就已經完全夠用,
3.2.2 服務器終端內設定防火墻
ubuntu@VM-0-6-ubuntu:~$ sudo ufw status
Status: inactive
ubuntu@VM-0-6-ubuntu:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? n
Aborted
這里我們看到防火墻處于關閉狀態,我們也可以選擇開啟防火墻,然后手動將22、80、443、5000、3306等埠開啟,但這里有一個大坑,就是當我們開啟防火墻的時候,終端會提示打開防火墻會斷開ssh連接,而ssh訪問的是服務器的22埠,如果我們開啟防火墻,很容易和服務器斷開連接后無法登錄,
ubuntu@VM-0-6-ubuntu:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
ubuntu@VM-0-6-ubuntu:~$ sudo ufw allow 22
Rule added
Rule added (v6)
ubuntu@VM-0-6-ubuntu:~$ sudo ufw status
Status: active
To Action From
-- ------ ----
22 ALLOW Anywhere
22 (v6) ALLOW Anywhere (v6)
如果幸運的話,我們開啟防火墻后仍可以保持和服務器的連接,那一定要趕快開啟22埠;如果沒來得及開啟22埠,我們就只能通過騰訊云控制臺提供的VNC登錄,在里面進行防火墻的設定:

上述設定完成后,我們就可以正常通過6.6.6.6:5000訪問到hello world頁面,
3.3 安裝與配置uwsgi
3.3.1 安裝uwsgi
uwsgi安裝在本文里采用的是原始碼安裝的方法,參考的鏈接如下(注意!按原教程方法可能出現報錯!):
uwsgi下載安裝配置(二)采用編譯的方式安裝uwsgi
首先,我們在專案目錄/home/ubuntu下新建一個uwsgi檔案夾,進入檔案夾中,將最新的uwsgi安裝包下載到該目錄下面:
(py37env) ubuntu@VM-0-6-ubuntu:~$ mkdir uwsgi
(py37env) ubuntu@VM-0-6-ubuntu:~$ ls
env test uwsgi
(py37env) ubuntu@VM-0-6-ubuntu:~$ cd uwsgi/
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi$ wget http://projects.unbit.it/downloads/uwsgi-latest.tar.gz
--2022-01-16 21:34:17-- http://projects.unbit.it/downloads/uwsgi-latest.tar.gz
Resolving projects.unbit.it (projects.unbit.it)... 148.251.4.146
Connecting to projects.unbit.it (projects.unbit.it)|148.251.4.146|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 804906 (786K)
Saving to: ‘uwsgi-latest.tar.gz’
uwsgi-latest.tar.gz 100%[====================================>] 786.04K 25.7KB/s in 26s
2022-01-16 21:34:44 (30.2 KB/s) - ‘uwsgi-latest.tar.gz’ saved [804906/804906]
解壓縮后,進入到最新版uwsgi的檔案夾下,開始構建:
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi$ tar -zxvf uwsgi-latest.tar.gz
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi$ ls
uwsgi-2.0.20 uwsgi-latest.tar.gz
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi$ cd uwsgi-2.0.20/
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi/uwsgi-2.0.20$ python3 uwsgiconfig.py --build
此時按照原教程會出現下述報錯:
In file included from plugins/python/python_plugin.c:1:0:
plugins/python/uwsgi_python.h:2:10: fatal error: Python.h: No such file or directory
#include <Python.h>
^~~~~~~~~~
compilation terminated.
一番查找后,解決辦法如下:
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi/uwsgi-2.0.20$ sudo apt-get install python3.7-dev
下載python3.7-dev包后,再次構建,發現構建成功:
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi/uwsgi-2.0.20$ sudo python3 uwsgiconfig.py --build
############## end of uWSGI configuration #############
total build time: 9 seconds
*** uWSGI is ready, launch it with ./uwsgi ***
接著運行install指令(為避免奇奇怪怪的錯誤出現,建議能用sudo盡量用sudo):
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi/uwsgi-2.0.20$ sudo python3 setup.py install
############## end of uWSGI configuration #############
total build time: 0 seconds
*** uWSGI is ready, launch it with /usr/local/bin/uwsgi ***
running build
running build_py
creating build
creating build/lib
copying uwsgidecorators.py -> build/lib
running install_lib
copying build/lib/uwsgidecorators.py -> /usr/local/lib/python3.7/dist-packages
byte-compiling /usr/local/lib/python3.7/dist-packages/uwsgidecorators.py to uwsgidecorators.cpython-37.pyc
running install_egg_info
running egg_info
creating uWSGI.egg-info
writing uWSGI.egg-info/PKG-INFO
writing dependency_links to uWSGI.egg-info/dependency_links.txt
writing top-level names to uWSGI.egg-info/top_level.txt
writing manifest file 'uWSGI.egg-info/SOURCES.txt'
reading manifest file 'uWSGI.egg-info/SOURCES.txt'
writing manifest file 'uWSGI.egg-info/SOURCES.txt'
Copying uWSGI.egg-info to /usr/local/lib/python3.7/dist-packages/uWSGI-2.0.20.egg-info
running install_scripts
通過ls命令可以看到當前目錄下多了可執行的uwsgi,但由于現在不是全域命令,需要設定一個軟鏈接:
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi/uwsgi-2.0.20$ sudo ln -s /home/ubuntu/uwsgi/uwsgi-2.0.20/uwsgi /usr/bin/uwsgi
回到專案目錄,進行測驗,看看是否可以全域使用uwsgi:
(py37env) ubuntu@VM-0-6-ubuntu:~/uwsgi/uwsgi-2.0.20$ cd ~
(py37env) ubuntu@VM-0-6-ubuntu:~$ uwsgi
*** Starting uWSGI 2.0.20 (64bit) on [Sun Jan 16 21:53:57 2022] ***
compiled with version: 7.5.0 on 16 January 2022 13:46:17
os: Linux-4.15.0-159-generic #167-Ubuntu SMP Tue Sep 21 08:55:05 UTC 2021
nodename: VM-0-6-ubuntu
machine: x86_64
clock source: unix
detected number of CPU cores: 1
current working directory: /home/ubuntu
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 7188
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
The -s/--socket option is missing and stdin is not a socket.
至此,uwsgi安裝成功,
3.3.2 配置與測驗uwsgi與flask連通
在這里首先要提醒讀者的一點是,測驗uwsgi與flask連通與最終測驗uwsgi、flask、nginx連通的uwsgi配置是不同的,且最根本的不同在于是采用http連接還是socket連接,我在一開始參考各種教程時忽略了這一點,導致我在安裝nginx前,一直無法通過外網訪問uwsgi+flask運行的結果(此處無法訪問是因為設定了socket連接,socket連接在沒有配置和啟動nginx時無法通過外網訪問),因此在本文的教程中,為直觀測驗uwsgi+flask的連接,我們先采取http連接,
回到專案目錄下的test檔案夾中,我們新建一個uwsgi.ini檔案,這個檔案就是用來啟動相應配置的uwsgi,我們在其中寫入一些最基本的引數(關于如何具體寫引數,我也不是很清楚,本文偏重于順利安裝),關鍵要注意設定成http而非socket:
(py37env) ubuntu@VM-0-6-ubuntu:~$ ls
env test uwsgi
(py37env) ubuntu@VM-0-6-ubuntu:~$ cd test
(py37env) ubuntu@VM-0-6-ubuntu:~/test$ ls
run.py
(py37env) ubuntu@VM-0-6-ubuntu:~/test$ vim uwsgi.ini
[uwsgi]
master = true
http=:5000
chdir = /home/ubuntu/test
wsgi-file=/home/ubuntu/test/run.py # 對應啟動flask的檔案
callable=app
processes=4
threads=2
buffer-size = 65536
vacuum=true
pidfile =/home/ubuntu/test/ubuntu/uwsgi.pid # 指定生成記錄pid檔案的地址
virtualenv=/home/ubuntu/env/py37env # 指定運行的python環境
配置完uwsgi,我們通過uwsgi啟動flask,并再次訪問6.6.6.6:5000,查看是否能正常訪問:
(py37env) ubuntu@VM-0-6-ubuntu:~/test$ uwsgi --ini uwsgi.ini
[uWSGI] getting INI configuration from uwsgi.ini
*** Starting uWSGI 2.0.20 (64bit) on [Sun Jan 16 22:09:20 2022] ***
compiled with version: 7.5.0 on 16 January 2022 13:46:17
os: Linux-4.15.0-159-generic #167-Ubuntu SMP Tue Sep 21 08:55:05 UTC 2021
nodename: VM-0-6-ubuntu
machine: x86_64
clock source: unix
detected number of CPU cores: 1
current working directory: /home/ubuntu/test
writing pidfile to /home/ubuntu/test/uwsgi.pid
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
chdir() to /home/ubuntu/test
your processes number limit is 7188
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on :5000 fd 4
uwsgi socket 0 bound to TCP address 127.0.0.1:39563 (port auto-assigned) fd 3
Python version: 3.7.5 (default, Dec 9 2021, 17:04:37) [GCC 8.4.0]
Set PythonHome to /home/ubuntu/env/py37env
Python main interpreter initialized at 0x564ba1da7da0
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 1031110 bytes (1006 KB) for 8 cores
*** Operational MODE: preforking+threaded ***
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x564ba1da7da0 pid: 25595 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 25595)
spawned uWSGI worker 1 (pid: 25598, cores: 2)
spawned uWSGI worker 2 (pid: 25599, cores: 2)
spawned uWSGI worker 3 (pid: 25600, cores: 2)
spawned uWSGI worker 4 (pid: 25601, cores: 2)
spawned uWSGI http 1 (pid: 25602)
訪問6.6.6.6:5000,頁面正常顯示hello world,至此uwsgi配置與測驗成功,
3.3.3 關閉uwsgi的命令
這里我給出一個比較方便的,可以和后來的nginx關閉命令一起記憶:
(py37env) ubuntu@VM-0-6-ubuntu:~/test$ pkill -9 uwsgi
關閉nginx就是把uwsgi換成nginx,
3.4 安裝與配置nginx
3.4.1 安裝nginx
本文安裝nginx采用的也是原始碼安裝,參考的鏈接如下:
ubuntu16.04原始碼編譯安裝nginx1.14.2
教程中給出的nginx版本較低,我們進入nginx.org官網,進行新版本的下載鏈接獲取,我目前獲取到的最新版本是1.20.2,下載鏈接為https://nginx.org/download/nginx-1.20.2.tar.gz,與安裝uwsgi類似,我們在/usr/local目錄下,新建nginx目錄,進入nginx目錄,通過wget進行安裝包下載,下載后進行解壓:
(py37env) ubuntu@VM-0-6-ubuntu:/usr/local$ sudo mkdir nginx
(py37env) ubuntu@VM-0-6-ubuntu:/usr/local$ ls
bin etc games include lib man nginx qcloud sa sbin share src yd.socket.server
(py37env) ubuntu@VM-0-6-ubuntu:/usr/local$ cd nginx
(py37env) ubuntu@VM-0-6-ubuntu:/usr/local/nginx$ sudo wget https://nginx.org/download/nginx-1.20.2.tar.gz
--2022-01-16 22:19:22-- https://nginx.org/download/nginx-1.20.2.tar.gz
Resolving nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:edb:5704::6, ...
Connecting to nginx.org (nginx.org)|3.125.197.172|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1062124 (1.0M) [application/octet-stream]
Saving to: ‘nginx-1.20.2.tar.gz’
nginx-1.20.2.tar.gz 100%[====================================>] 1.01M 17.6KB/s in 55s
2022-01-16 22:20:19 (18.9 KB/s) - ‘nginx-1.20.2.tar.gz’ saved [1062124/1062124]
(py37env) ubuntu@VM-0-6-ubuntu:/usr/local/nginx$ sudo tar -zxvf nginx-1.20.2.tar.gz
進入解壓好的nginx-1.20.2檔案夾中,在編譯源代碼前,運行下列命令來安裝依賴包:
(py37env) ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo apt-get update
Hit:1 http://mirrors.tencentyun.com/ubuntu bionic InRelease
Hit:2 http://mirrors.tencentyun.com/ubuntu bionic-security InRelease
Hit:3 http://mirrors.tencentyun.com/ubuntu bionic-updates InRelease
Traceback (most recent call last):
File "/usr/lib/cnf-update-db", line 8, in <module>
from CommandNotFound.db.creator import DbCreator
File "/usr/lib/python3/dist-packages/CommandNotFound/db/creator.py", line 11, in <module>
import apt_pkg
ModuleNotFoundError: No module named 'apt_pkg'
Reading package lists... Done
E: Problem executing scripts APT::Update::Post-Invoke-Success 'if /usr/bin/test -w /var/lib/command-not-found/ -a -e /usr/lib/cnf-update-db; then /usr/lib/cnf-update-db > /dev/null; fi'
E: Sub-process returned an error code
可以看到此處apt-get update出錯,根據錯誤資訊,我參考了如下鏈接的解決方式:
【問題解決】Linux下python報錯:ModuleNotFoundError: No module named ‘apt_pkg‘
該問題是我們前文進行python升級導致,我們先退出虛擬環境,然后按照教程中的指令進行錯誤修復(教程中的python3.8都換成我們對應的python3.7版本):
(py37env) ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ deactivate
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo apt-get remove --purge python-apt
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package 'python-apt' is not installed, so not removed
The following packages were automatically installed and are no longer required:
amd64-microcode intel-microcode iucode-tool
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 65 not upgraded.
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo apt-get install -f -y python3-apt
Reading package lists... Done
Building dependency tree
Reading state information... Done
python3-apt is already the newest version (1.6.5ubuntu0.7).
The following packages were automatically installed and are no longer required:
amd64-microcode intel-microcode iucode-tool
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 65 not upgraded.
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ cd /usr/lib/python3/dist-packages/
ubuntu@VM-0-6-ubuntu:/usr/lib/python3/dist-packages$ sudo cp apt_pkg.cpython-36m-x86_64-linux-gnu.so apt_pkg.cpython-37m-x86_64-linux-gnu.so
ubuntu@VM-0-6-ubuntu:/usr/lib/python3/dist-packages$ sudo ln -s apt_pkg.cpython-37m-x86_64-linux-gnu.so apt_pkg.so
回到/usr/local/nginx/nginx-1.20.2目錄,再次嘗試update:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo apt-get update
Hit:1 http://mirrors.tencentyun.com/ubuntu bionic InRelease
Hit:2 http://mirrors.tencentyun.com/ubuntu bionic-security InRelease
Hit:3 http://mirrors.tencentyun.com/ubuntu bionic-updates InRelease
Reading package lists... Done
此時已恢復正常,我們繼續相關依賴的安裝和nginx的編譯:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo apt-get install libpcre3 libpcre3-dev zlib1g-dev build-essential
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo ./configure
Configuration summary
+ using system PCRE library
+ OpenSSL library is not used
+ using system zlib library
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
當然,這里埋了一個伏筆,我們在后續要進行https的配置時,會出現一個報錯(具體見后文),原因就出在我們在configure時,沒有預先設定支持https,但是不急,我們可以先把這個問題放在這里,繼續nginx的安裝:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo make
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo make install
切到路徑:/usr/local/nginx/sbin,執行nginx啟動命令,測驗nginx是否安裝成功:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/sbin$ sudo ./nginx
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/sbin$ ps -ef | grep nginx
root 2505 1 0 22:38 ? 00:00:00 nginx: master process ./nginx
nobody 2506 2505 0 22:38 ? 00:00:00 nginx: worker process
ubuntu 2554 12702 0 22:38 pts/0 00:00:00 grep --color=auto nginx
nginx安裝成功,并設定可以全域啟動的nginx命令的軟鏈接:
sudo ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
我們回到專案目錄/home/ubuntu下,先關閉已啟動的nginx,測驗nginx命令是否已經全域生效:
ubuntu@VM-0-6-ubuntu:~$ sudo pkill -9 nginx
ubuntu@VM-0-6-ubuntu:~$ sudo nginx
ubuntu@VM-0-6-ubuntu:~$ ps -ef | grep nginx
root 3075 1 0 22:41 ? 00:00:00 nginx: master process nginx
nobody 3076 3075 0 22:41 ? 00:00:00 nginx: worker process
ubuntu 3084 12702 0 22:41 pts/0 00:00:00 grep --color=auto nginx
至此,nginx安裝成功,
3.4.2 配置nginx與測驗flask+uwsgi+nginx連通性
nginx安裝成功后,我們進入/usr/local/nginx/conf目錄中查看并修改nginx.conf,nginx啟動時會默認加載這個組態檔:
ubuntu@VM-0-6-ubuntu:~$ cd /usr/local/nginx/conf
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/conf$ ls
fastcgi.conf koi-utf nginx.conf uwsgi_params
fastcgi.conf.default koi-win nginx.conf.default uwsgi_params.default
fastcgi_params mime.types scgi_params win-utf
fastcgi_params.default mime.types.default scgi_params.default
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/conf$ sudo vim nginx.conf
user ubuntu;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:5000;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# HTTPS Server
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
上述組態檔中值得注意的幾個點:
- 第一行user后更換成當前服務器登錄的用戶名
- 需要flask后端路由的路徑要在配置里面加上include uwsgi_params;和uwsgi_pass 127.0.0.1:5000;這兩行
- listen后面是nginx監聽埠,打開監聽埠的方法見上述安全組和防火墻配置方法
- server_name后填寫服務器地址或域名,如用localhost則表示此服務器地址
配置好后,我們還要記得把uwsgi組態檔中連接方法改為socket,這樣才會把uwsgi和nginx連通:
[uwsgi]
master = true
socket=:5000
chdir = /home/ubuntu/test
wsgi-file=/home/ubuntu/test/run.py
callable=app
processes=4
threads=2
buffer-size = 65536
vacuum=true
pidfile =/home/ubuntu/test/uwsgi.pid
virtualenv=/home/ubuntu/env/py37env
啟動uwsgi和nginx,訪問瀏覽器6.6.6.6:5000:
ubuntu@VM-0-6-ubuntu:~/test$ sudo nginx
ubuntu@VM-0-6-ubuntu:~/test$ uwsgi --ini uwsgi.ini
我們發現此時無法正常訪問,這是因為配置nginx后,nginx會監聽5000埠的內容,并把5000埠收到的資訊轉交到80埠,我們此時直接在瀏覽器中輸入6.6.6.6,就可以正常訪問到hello world頁面,
至此,flask+uwsgi+nginx初始配置完成,
3.5 https相關配置
我們看到上述組態檔中有一部分被注釋掉的部分,那一部分正是對https的配置,本專案由于在騰訊云服務器上構建,因此下述流程適用于騰訊云用戶,
3.5.1 SSL證書安裝部署
我參考了騰訊云官方給出的SSL證書安裝部署方法,鏈接如下:
Nginx 服務器 SSL 證書安裝部署
3.5.2 修改nginx組態檔
我們把從騰訊云服務器上下載的證書上傳到服務器上后,在nginx組態檔中增加https配置:
user ubuntu;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:5000;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# HTTPS Server
server {
listen 443 ssl;
server_name localhost;
ssl_certificate cert.pem; # 注意修改成自己的xxx_bundle.crt路徑地址
ssl_certificate_key cert.key; # 注意修改成自己的xxx.key路徑地址
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:5000;
}
}
}
啟動nginx,我們會發現有報錯:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/conf$ sudo nginx
nginx: [emerg] the "ssl" parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf:33
如前文所述,這是因為我們一開始編譯nginx時,并沒有將https配置功能安裝到nginx中,解決方法我參考了下述鏈接:
nginx: [emerg] the “ssl” parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf:37
我們回到nginx原始碼安裝地址中,查看nginx安裝資訊:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/conf$ cd /usr/local/nginx/nginx-1.20.2/
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ nginx -V
nginx version: nginx/1.20.2
built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
configure arguments:
可以看到,起初我們編譯時并沒有設定configure arguments,因此我們需要重新編譯,將https模塊加進去:
sudo ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.
出現報錯,缺少OpenSSL庫,這個簡單,我們用apt安裝之后再次嘗試編譯:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo apt-get install OpenSSL
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package OpenSSL
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo apt-get install openssl
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
amd64-microcode intel-microcode iucode-tool
Use 'sudo apt autoremove' to remove them.
The following packages will be upgraded:
openssl
1 upgraded, 0 newly installed, 0 to remove and 64 not upgraded.
Need to get 613 kB of archives.
After this operation, 1,024 B disk space will be freed.
Get:1 http://mirrors.tencentyun.com/ubuntu bionic-updates/main amd64 openssl amd64 1.1.1-1ubuntu2.1~18.04.14 [613 kB]
Fetched 613 kB in 1s (999 kB/s)
(Reading database ... 81640 files and directories currently installed.)
Preparing to unpack .../openssl_1.1.1-1ubuntu2.1~18.04.14_amd64.deb ...
Unpacking openssl (1.1.1-1ubuntu2.1~18.04.14) over (1.1.1-1ubuntu2.1~18.04.13) ...
Setting up openssl (1.1.1-1ubuntu2.1~18.04.14) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
這里需要注意一點,openssl一定要小寫,否則會報錯,再次嘗試編譯:
./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.
仍然報錯,查詢資料后,發現ubuntu系統還要安裝libssl-dev:
sudo apt-get install libssl-dev
sudo ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
Configuration summary
+ using system PCRE library
+ using system OpenSSL library
+ using system zlib library
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
這回終于成功了,我們繼續執行make命令(注意make install不要執行):
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo make
接著備份已安裝好的nginx:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
如果nginx正在運行,停止nginx后,運行下列命令:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ sudo cp ./objs/nginx /usr/local/nginx/sbin/
再次查看nginx安裝資訊:
ubuntu@VM-0-6-ubuntu:/usr/local/nginx/nginx-1.20.2$ nginx -V
nginx version: nginx/1.20.2
built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
built with OpenSSL 1.1.1 11 Sep 2018
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
可以看到nginx的https模塊已配置成功!我們重新啟動nginx和uwsgi,訪問瀏覽器https://6.6.6.6/,看看頁面能否正常訪問:
ubuntu@VM-0-6-ubuntu:~/test$ sudo nginx
ubuntu@VM-0-6-ubuntu:~/test$ uwsgi --ini uwsgi.ini
可以看到頁面正常顯示hello world,且此時通過https訪問,至此nginx+uwsgi+flask+https的配置成功,后續讀者根據自身專案需求調整其中的uwsgi.ini和nginx.conf即可,
3.6 安裝與配置mysql資料庫
這部分本文不作為重點,因此只給出親測有效的安裝配置鏈接:
Ubuntu18.04 安裝MySQL
按照這篇文章給出的步驟安裝配置,基本不會出現任何問題,
另附mysql資料檔案遷移的教程鏈接,親測有效:
在ubuntu上將mysql資料庫資料遷移到另一臺服務器上
4 部署程序中的一些感想
- 一定要有耐心,如果哪一步配置錯了導致整個流程亂掉了,與其陷入查找資料的死回圈里,不如重置服務器環境重新配置
- 一定要把自己查過的行之有效的資料鏈接保存下來,網上相關教程很多,但真正自己從頭到尾實踐一遍試錯的并不多
- 一個教程配置失敗的時候,要果斷更換教程,網上給出的教程都不是萬能的,都是在一定前提條件下才能生效的配置方法
- 也歡迎大家在評論區指出配置程序中的問題,有一些沒有在配置主流程里涉及的報錯的解決方法我暫時沒有放上去,歡迎大家有問題在評論區里交流意見,讓部署不再成為一件讓人頭疼的事情
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/413873.html
標籤:其他
上一篇:計算機網路筆記(第一章)
