雖然現在docker容器技術成熟且好用,但是Nginx+uWsgi作為經典的web部署還是快捷而穩定的,所以還是記錄下這次的部署(阿里雲伺服器),方便以後如果需要的時候翻閱。 環境引數:
Centos 7
Python 3.6
複製程式碼
部署前的準備
免密登入阿里雲
阿里雲建立完例項後,通過ssh root@xx.xx.xx.xx -p 22
輸入密碼後登入上雲服務(因為是個人使用,我嫌棄每次都需要輸入密碼就設定了無密碼登入),按以下步驟在伺服器上生成金鑰對:
[root@iZj6c37pa56zt0xet2tcqeZ ~]# ssh-keygen <== 建立金鑰對
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): <== 按 Enter
Enter passphrase (empty for no passphrase): <== 輸入金鑰鎖碼,或直接按 Enter 留空
Enter same passphrase again: <== 再輸入一遍金鑰鎖碼
Your identification has been saved in /root/.ssh/id_rsa.<== 私鑰
Your public key has been saved in /root/.ssh/id_rsa.pub.<== 公鑰
The key fingerprint is:
xxxxxxx
複製程式碼
金鑰鎖碼在使用私鑰時必須輸入,這樣就可以保護私鑰不被盜用。當然,也可以留空,實現無密碼登入。 現在,在 root 使用者的家目錄中生成了一個 .ssh的隱藏目錄,內含兩個金鑰檔案:id_rsa 為私鑰,id_rsa.pub 為公鑰。
- 在伺服器上安裝剛剛生成的公鑰,並修改檔案許可權。
[root@iZj6c37pa56zt0xet2tcqeZ ~]# cd .ssh
[root@iZj6c37pa56zt0xet2tcqeZ .ssh]# cat id_rsa.pub >> authorized_keys
[root@iZj6c37pa56zt0xet2tcqeZ .ssh]# chmod 600 authorized_keys
[root@iZj6c37pa56zt0xet2tcqeZ .ssh]# chmod 700 ~/.ssh
複製程式碼
這裡囉嗦下許可權的相關linux知識吧:
- 修改許可權中數字的第一位表示擁有者,第二位是群組,第三位是其他
- 其中的每個數字表示讀,寫,可執行的擁有許可權,比如數字600中的數字6,可以拆解成110,
1*2^2+1*2^1+0*2^0=6
,所以表示檔案具有讀,寫,無可執行許可權。
- 設定 SSH,開啟金鑰登入功能
- 編輯 /etc/ssh/sshd_config 檔案,進行如下設定:
RSAAuthentication yes
PubkeyAuthentication yes
複製程式碼
- 另外,請留意 root 使用者能否通過 SSH 登入:
PermitRootLogin yes
- 最後,重啟 SSH 服務:
service sshd restart
- 通過scp命令將私鑰下載到本地
scp root@xx.xx.xx.xx:/root/.ssh/id_rsa /Users/fangzjty/Desktop/
。 - 在個人使用者下找到.ssh位置(個人是mac電腦,windows的機子可以到網上查詢下.ssh的位置),然後建立一個
mysys-id_rsa
檔案,名稱可以自己取,然後將下載的私鑰內容拷貝到這個檔案裡(當然你也可以直接複製原來的私鑰,要不要修改名稱看你以後會不會有新的服務)。 - 建立一個config檔案,在裡面輸入以下內容並儲存
User root
Host xx.xx.xx.xx
IdentityFile ~/.ssh/mysys-id_rsa
Port 22
複製程式碼
User表示登入的使用者名稱,Host是你要連線的主機名(域名或者ip地址),IdentityFile表示伺服器私鑰檔案的位置,Port就是登入的埠
以上就完成了免密登入的設定,然後就可以通過ssh root@xx.xx.xx.xx -p 22
登入雲伺服器了,當然這只是一種設定免密登入的方式,通過公鑰和私鑰的配對完成登入驗證,這裡是從伺服器上拿私鑰,你也可以把自己的公鑰上傳到伺服器,寫入伺服器.ssh下的authorized_keys來允許你的遠端免密登入
上傳專案檔案和專案架構
專案架構圖如下:
這裡就不用直接建立的工程講解了,那個比較簡單,且不需要安裝mysql。該框架下的app.py是專案的啟動檔案,app核心物件的例項名稱也是app。 然後登入雲伺服器,建立一個資料夾,命令:mkdir flaskproject
之後將專案上傳上這個資料夾下,或者自己上傳github,使用git clone xxxxx
命令從github上拉取(github現在支援私有工程了,當然使用git需要安裝相應的git命令)。
tar -cvf blog.tar blog/* <==壓縮blog專案,方便上傳
scp -r /Users/xxxx/Documents/pyproject/flaskproject/blog.tar root@xx.xx.xx.xx:/root/flaskproject/ <==將本地專案上傳到雲伺服器
tar -xvf blog.tar <==解壓blog專案
複製程式碼
安裝Python環境
yum update <==更新下yum
yum install zlib-devel bzip2-devel sqlite sqlite-devel openssl-devel
wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz
tar -xvf Python-3.6.3.tgz
cd Python-3.6.3/
./configure <==編譯Python
make
make install
複製程式碼
如果在./configure
時編譯失敗可能是需要安裝gcc/g++,此時需要輸入:yum install gcc-g++
安裝成功之後,就是建立虛擬環境,可以用virtualenv,virtualenvwrapper或者pipenv,看你個人習慣。
cd <==回到主目錄
pip3 install --upgrade pip <==一般會提示你更新pip,因為用的python3,所以更新pip3
pip3 install pipenv
mkdir flaskvenv <==虛擬環境的檔案目錄
cd flaskvenv/
mkdir blogvenv
cd blogvenv/
pipenv --python 3.6 <==建立虛擬環境
pipenv shell <==執行虛擬環境
pip install -r /root/flaskproject/blog/venv/requirements.txt <==匯入blog專案的依賴庫
pipenv graph <==檢視依賴庫是否匯入
exit <==退出虛擬環境
複製程式碼
pipenv的命令可以通過github上查詢專案檢視,也可以通過pipenv --help檢視命令
安裝mysql
- 安裝mysql
wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
yum localinstall mysql57-community-release-el7-8.noarch.rpm
yum repolist enabled | grep "mysql.*-community.*" <==檢視mysql是否安裝成功,成功見mysql模組下的圖一
yum install mysql-community-server <==安裝mysql
systemctl start mysqld <==啟動mysql服務
systemctl enable mysqld <==設定開機啟動
systemctl daemon-reload
grep 'temporary password' /var/log/mysqld.log <==檢視mysql生成的預設密碼
mysql -uroot -p <==輸入預設密碼
複製程式碼
進入mysql之後:
mysql> set password for 'root'@'localhost'=password('YourPassword'); <==修改密碼
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'xxxxx' WITH GRANT OPTION; <==賦予許可權所有遠端主機都能連線上mysql
mysql> FLUSH PRIVILEGES;
複製程式碼
重啟mysql:systemctl restart mysqld
圖一:
設定密碼有一定規則,如果想簡單點可以把規則關掉或者降低規則標準:mysql> set global validate_password_policy=0;
Mysql為了安全性,在預設情況下使用者只允許在本地登入,可以使用以上方法,當然也可以通過給固定使用者分配許可權的方式實現。
-
測試mysql的外部連線 要連線上阿里雲上的服務,需要在阿里雲的安全組中開放埠,具體規則阿里雲上描述的比較詳細了,就不說了,在阿里雲上加上3306的埠即可。 然後在本地中通過視覺化mysql的相關工具進行連通測試,顯示連線成功。
-
建立對應資料庫 根據你自己的專案需要建立對應的資料庫
uwsgi安裝
- 安裝uwsgi
pip3 install uwsgi <==安裝uwsgi
cd /root/flaskproject/blog
vim uwsgi_blog.ini
複製程式碼
uwsgi_blog.ini的配置內容如下
[uwsgi]
chdir = /root/flaskproject/blog
socket = /root/flaskproject/blog/script/uwsgi.sock
#socket = 127.0.0.1:3021
master = 1
processes = 2
virtualenv=/root/.local/share/virtualenvs/blogvenv-7HO3iOv9
callable = app
wsgi-file = app.py
daemonize=/root/flasklog/blog/uwsgi.log
複製程式碼
- chdir表示執行目錄
- socket是用於和nginx互動的連通網路(docker中的network),2個本地的應用如果需要互動,需要有一個連通橋樑,這個socker就是nginx和uwsgi的連通橋樑。可以使用IP+埠,也可以使用.sock檔案進行連通(.scok檔案建立稍後描述)
- master主程式數量
- processes子程式數量
- virtualenv虛擬環境地址,這個地址通過在
cd /root/flaskvenv/blogvenv
,然後通過pipenv --venv
獲取到 - callable表示flask專案例項的名稱,比如程式碼中app = Flask(name),所以這裡為app
- wsgi-file專案的啟動檔案
- daemonizeuwsgi的日誌(這個檔案自己根據路徑來建立檔案和資料夾,這裡就不說了)
建立uwsgi.sock檔案
cd /root/flaskproject/blog
mkdir script
cd script
touch uwsgi.sock
chmod 666 uwsgi.sock
cd ..
chmod 666 script
複製程式碼
- 測試uwsgi
使用
uwsgi --ini /root/flaskproject/blog/uwsgi_blog.ini
測試uwsgi是否成功,成功則會出現以下提示: [uWSGI] getting INI configuration from /root/flaskproject/blog/uwsgi_blog.ini 然後檢視uwsgi.log是否有錯誤資訊:more /root/flasklog/blog/uwsgi.log
。如果沒有錯誤並且有類似資訊則表示uwsgi安裝和部署沒有問題: WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x1bb0880 pid: 18601 (default app)
如果出現類似unable to load app 0 (mountpoint='') (callable not found or import error)
資訊,那大概率是你uwsgi_blog.ini的配置出現問題了,看看各引數和說明。
nginx安裝
yum install nginx
cd /root/flaskproject/blog
vim nginx_blog.conf
複製程式碼
nginx_blog.conf的內容如下:
server {
listen 8021; #監聽埠
server_name xx.xx.xx.xx; #伺服器公網IP或者域名
charset utf-8;
access_log /root/flasklog/blog/access.log;
error_log /root/flasklog/blog/error.log;
location / {
include uwsgi_params;
# uwsgi_pass 127.0.0.1:3021;
uwsgi_pass unix:/root/flaskproject/blog/script/uwsgi.sock;
# uwsgi_param UWSGI_PYHOME /root/.local/share/virtualenvs/blogvenv-lyQ6xKaC; # 指向虛擬環境目錄
# uwsgi_param UWSGI_CHDIR /root/flaskproject/blog; # 指向網站根目錄
# uwsgi_param UWSGI_SCRIPT app; # 指定啟動程式
}
}
複製程式碼
填寫好自己需要暴露出來的埠和公網ip,並建立access_log和error_log檔案,uwsgi_pass就是連線uwsgi的橋樑,保持和uwsgi中的配置一致就好了。
之後將該配置軟連線到conf.d目錄下:ln -s /root/flaskproject/blog/nginx_blog.conf /etc/nginx/conf.d/
,因為nginx.conf中會include下的所有檔案(見nginx.conf的配置檔案),所以只要連結到該目錄下,也只用新增server就可以了。
nginx -t -c /etc/nginx/nginx.conf <==檢查nginx配置是否有語法錯誤
systemctl start nginx.service <==啟動nginx
複製程式碼
這時候,如果你是用uwsgi.sock來作為橋樑溝通,就會有問題,你可以通過curl 127.0.0.1:port
(port更換為你要測試的埠號),然後就可以到你自己建立的nginx的error.log中檢視到錯誤資訊,發現提示:“1 connect() to unix:/root/flaskproject/blog
/script/uwsgi.sock failed (13: Permission denied) while connecting to upstream。”,說的是沒有連線uwsgi.sock的許可權,可是明明開放了所有許可權的,這點我也不是很明白,然後通過修改nginx.conf的下的使用者組解決這個問題:vim /etc/nginx/nginx.conf
,之後修改第一個的user nginx;
為user root;
然後重新啟動nginx:nginx -s reload
。
這時,nginx的部署在本地就成功了,然後需要到阿里雲的安全組下開通埠,比如我上面需要開8021埠。之後在如果無法連線可能因為防火牆攔截了,需要讓該埠可以被防火牆放行(Centos 7以上是firewall,Centos 6上是iptables,雖然firewall也是基於iptables上實現的):
firewall-cmd --zone=public --add-port=8021/tcp --permanent
firewall-cmd --reload
複製程式碼
至此,你就可以通過外網的地址訪問服務了。記得在你沒做完一個功能塊的時候測試下是否成功,免得最後的時候去測試但找不到來是那塊出了問題。
資源: