【百度云搜索竭贩,搜各種資料:http://bdy.lqkweb.com】
【搜網(wǎng)盤,搜各種資料:http://www.swpan.cn】
本文翻譯自The Flask Mega-Tutorial Part XVII: Deployment on Linux
這是Flask Mega-Tutorial系列的第十七部分突诬,我將把Microblog部署到Linux服務(wù)器。
在本章中,我將談到Microblog應(yīng)用生命周期中的一個(gè)里程碑梧奢,因?yàn)槲覍⒂懻撊绾螌?yīng)用部署到生產(chǎn)服務(wù)器上担神,以便真實(shí)用戶可以訪問它楼吃。
部署的主題非常廣泛,因此不可能在這里涵蓋所有范疇。 本章致力于探討傳統(tǒng)托管方式孩锡,包括Ubuntu發(fā)行版的Linux服務(wù)器和流行的樹莓派微機(jī)酷宵。 我將在后面的章節(jié)中介紹其他選項(xiàng),例如云和容器部署躬窜。
本章的GitHub鏈接為:Browse, Zip, Diff.
傳統(tǒng)托管
當(dāng)提到“傳統(tǒng)托管”時(shí)浇垦,意思是應(yīng)用是手動(dòng)或通過原始服務(wù)器機(jī)器上的腳本安裝部署的。 該過程涉及安裝應(yīng)用程序荣挨、其依賴項(xiàng)和生產(chǎn)規(guī)模的Web服務(wù)器男韧,并配置系統(tǒng)以確保其安全。
當(dāng)你要部署自己的項(xiàng)目時(shí)垦沉,要問的第一個(gè)問題是在哪找服務(wù)器煌抒。 目前有很多經(jīng)濟(jì)的托管服務(wù)。 只需每月5美元厕倍,Digital Ocean寡壮,Linode或Amazon Lightsail就可以租借一臺(tái)虛擬化Linux服務(wù)器(Linode和Digital Ocean為其入門級(jí)服務(wù)器提供1GB RAM,而亞馬遜僅提供512MB)給你運(yùn)行部署實(shí)驗(yàn)讹弯。 如果你一分錢都不愿意花况既,那么Vagrant和VirtualBox組合而成的工具,可以讓你在自己的計(jì)算機(jī)上創(chuàng)建一個(gè)與付費(fèi)服務(wù)器類似的虛擬服務(wù)器组民。
就技術(shù)角度而言棒仍,該應(yīng)用可以部署在任何主流操作系統(tǒng)上,包括各種開放源代碼的Linux和BSD發(fā)行版以及商用的OS X(OS X是一個(gè)開源和商業(yè)的混種臭胜,因?yàn)樗陂_源BSD衍生產(chǎn)品Darwin)和Microsoft Windows莫其。
由于OS X和Windows是的桌面操作系統(tǒng),不是作為服務(wù)器的最佳選擇耸三,因此不是首選乱陡。 Linux或BSD操作系統(tǒng)之間的選擇很大程度上取決于愛好,所以我將選擇其中更受歡迎的Linux仪壮。 而Linux發(fā)行版中憨颠,我將再次選擇受歡迎的Ubuntu。
創(chuàng)建Ubuntu服務(wù)器
如果你有興趣與我一起部署积锅,那么就需要一臺(tái)服務(wù)器才能開始工作爽彤。 為你推薦兩種選擇,一種是付費(fèi)的缚陷,另一種是免費(fèi)的适篙。 如果你愿意花一點(diǎn)錢,可以在Digital Ocean箫爷,Linode或Amazon Lightsail上注冊(cè)一個(gè)賬戶嚷节,并創(chuàng)建一個(gè)Ubuntu 16.04鏡像的虛擬服務(wù)器铆铆。 你應(yīng)該使用最低配置的服務(wù)器,在我寫這篇文章的時(shí)候丹喻,三家的最低配置都是每月5美元薄货。 開銷是按照服務(wù)器啟動(dòng)的小時(shí)數(shù)進(jìn)行比例計(jì)算的,因此碍论,如果你創(chuàng)建服務(wù)器后谅猾,使用幾個(gè)小時(shí)然后刪除它,那么有可能你只需支付美分級(jí)別的費(fèi)用鳍悠。
免費(fèi)的方案基于你的計(jì)算機(jī)上可以運(yùn)行虛擬機(jī)税娜。 要使用此選項(xiàng),請(qǐng)?jiān)谀愕臋C(jī)器上安裝Vagrant和VirtualBox藏研,然后創(chuàng)建一個(gè)名為Vagrantfile的文件并用以下內(nèi)容來描述虛擬機(jī)的規(guī)格:
Vagrantfile:Vagrant配置敬矩。
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
end
end
該文件配置了一個(gè)帶有1GB RAM的Ubuntu 16.04服務(wù)器,你可以用其IP地址192.168.33.10來訪問該服務(wù)器蠢挡。 要?jiǎng)?chuàng)建服務(wù)器弧岳,請(qǐng)運(yùn)行以下命令:
$ vagrant up
請(qǐng)參閱Vagrant 命令行文檔了解其他管理虛擬服務(wù)器的選項(xiàng)。
使用SSH客戶端
你的服務(wù)器處于后端业踏,所以不需要像個(gè)人計(jì)算機(jī)上那樣擁有桌面禽炬。 你可以通過SSH客戶端連接到服務(wù)器,并運(yùn)行命令行進(jìn)行交互勤家。 如果你使用的是Linux或Mac OS X腹尖,則可能已經(jīng)安裝了OpenSSH。 如果你使用Microsoft Windows伐脖,Cygwin热幔,Git和Windows Subsystem for Linux提供OpenSSH,因此你可以安裝這些選項(xiàng)中的任何一個(gè)讼庇。
如果你正在使用來自第三方提供商的虛擬服務(wù)器绎巨,則在創(chuàng)建服務(wù)器時(shí),會(huì)為其分配IP地址巫俺。 你可以使用以下命令打開終端會(huì)話來連接到該服務(wù)器:
$ ssh root@<server-ip-address>
系統(tǒng)會(huì)提示你輸入密碼认烁。密碼已在創(chuàng)建服務(wù)器后自動(dòng)生成并顯示給你肿男,或者你自己指定了密碼介汹。
如果你使用的是Vagrant VM,則可以使用以下命令打開終端會(huì)話:
$ vagrant ssh
如果你使用的是Windows并且擁有Vagrant虛擬機(jī)舶沛,請(qǐng)注意你需要從可以調(diào)用ssh
命令的shell運(yùn)行上述命令嘹承。
免密登錄
如果你使用的是Vagrant虛擬機(jī),那么可以跳過本節(jié)如庭,因?yàn)槟愕奶摂M機(jī)已正確配置為使用名為ubuntu
的非root帳戶叹卷,Vagrant不用輸入密碼就可以自動(dòng)登錄撼港。
要是你使用的是虛擬服務(wù)器,則建議創(chuàng)建一個(gè)常規(guī)用戶來完成你的部署工作骤竹,并配置此帳戶以便在不使用密碼的情況下登錄帝牡,這么做最初看起來似乎是一個(gè)糟糕的主意, 之后你會(huì)發(fā)現(xiàn)它不僅更方便蒙揣,而且更安全靶溜。
我將創(chuàng)建一個(gè)名為ubuntu
的用戶帳戶(如果你愿意,可以使用其他名稱)懒震。 要?jiǎng)?chuàng)建這個(gè)用戶罩息,請(qǐng)使用前一節(jié)中的ssh
指令登錄到你的服務(wù)器的root帳戶,然后鍵入以下命令來創(chuàng)建用戶个扰,給它sudo
權(quán)限并最終切換到它:
$ adduser --gecos "" ubuntu
$ usermod -aG sudo ubuntu
$ su ubuntu
現(xiàn)在我要配置這個(gè)新的ubuntu
帳戶來使用public key認(rèn)證瓷炮,以便你可以免密登錄。
先不管服務(wù)器上打開的終端會(huì)話递宅,然后在本地計(jì)算機(jī)上啟動(dòng)第二個(gè)終端娘香。 如果你使用的是Windows,這需要是可以訪問ssh
命令的終端办龄,所以它可能是一個(gè)bash
或者類似的提示符的終端茅主,而不是本地的Windows終端。 在該終端會(huì)話中土榴,檢查~/.ssh目錄的內(nèi)容:
$ ls ~/.ssh
id_rsa id_rsa.pub
如果目錄列表顯示如上所述的名為id_rsa和id_rsa.pub的文件诀姚,那么你已經(jīng)有一個(gè)密鑰。 如果沒有這兩個(gè)文件玷禽,或者根本沒有~/.ssh目錄赫段,則你需要運(yùn)行以下命令(也是OpenSSH工具集的一部分)來創(chuàng)建SSH密鑰對(duì):
$ ssh-keygen
此應(yīng)用程序?qū)⑻崾灸爿斎胍恍﹥?nèi)容,為此我建議你在所有提示中按Enter以接受默認(rèn)設(shè)置矢赁。 你當(dāng)然也可以做一些設(shè)置糯笙,如果你知道這么做意味著什么的話。
運(yùn)行此命令后撩银,應(yīng)該有上面列出的兩個(gè)文件了给涕。 文件id_rsa.pub是你的公鑰,這是一個(gè)你將提供給第三方的文件额获,用于識(shí)別你的身份够庙。 id_rsa文件是你的私鑰,不應(yīng)與任何人共享抄邀。
你現(xiàn)在需要將公鑰配置為服務(wù)器中的授權(quán)主機(jī)耘眨。 在你自己的計(jì)算機(jī)上打開的終端上,將公鑰打印到屏幕上:
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCjw....F8Xv4f/0+7WT miguel@miguelspc
這將是一個(gè)非常長的字符序列境肾,顯示時(shí)可能跨越多行(但實(shí)際上只有一行)剔难。 你需要將此數(shù)據(jù)復(fù)制到剪貼板胆屿,然后切換回遠(yuǎn)程服務(wù)器上的終端,你將在其中運(yùn)行以下命令來存儲(chǔ)公鑰:
$ echo <paste-your-key-here> >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
免密登錄現(xiàn)在應(yīng)該可以工作了偶宫。 背后邏輯是非迹,你機(jī)器上的ssh
會(huì)用私鑰執(zhí)行加密操作來向服務(wù)器標(biāo)識(shí)自己。 然后服務(wù)器使用你的公鑰驗(yàn)證操作是否有效纯趋。
你現(xiàn)在可以注銷ubuntu
會(huì)話彻秆,然后注銷root
會(huì)話,然后嘗試直接登錄到ubuntu
帳戶:
$ ssh ubuntu@<server-ip-address>
這一次不用輸入密碼就登錄了结闸!
保護(hù)你的服務(wù)器
為了最大限度地降低服務(wù)器受到攻擊的風(fēng)險(xiǎn)唇兑,你可以采取一些措施來關(guān)閉攻擊者可能訪問的大量潛在漏洞。
我要做的第一個(gè)更改是禁用root用戶通過SSH登錄桦锄。 你現(xiàn)在可以無密碼地訪問ubuntu
帳戶扎附,并且可以通過sudo
從該帳戶運(yùn)行管理員命令,因此實(shí)際上不需要暴露root帳戶结耀。 要禁用root登錄留夜,你需要編輯服務(wù)器上的/etc/ssh/sshd_config文件。 你可能在你的服務(wù)器上安裝了vi
和nano
文本編輯器图甜,你可以用它來編輯文件(如果你不熟悉這兩種文件編輯器碍粥,可以首先嘗試nano
)。 由于SSH配置對(duì)普通用戶是不可訪問的黑毅,所以你需要在編輯器命令前添加sudo
(即sudo vi /etc/ssh/sshd_config
)嚼摩。 你需要更改此文件中的單行:
/etc/ssh/sshd_config:禁止root登錄。
PermitRootLogin no
請(qǐng)注意矿瘦,要進(jìn)行此更改枕面,你需要找到以PermitRootLogin
開頭的行(找不到就新建一行)并將該值更改為no
。
下一個(gè)更改在同一個(gè)文件中缚去。 現(xiàn)在我要為所有帳戶禁用密碼登錄潮秘。 你有一個(gè)無密碼的登錄設(shè)置,所以沒有必要允許密碼易结。 如果你對(duì)完全禁用密碼感到緊張枕荞,可以跳過此更改,但對(duì)于生產(chǎn)服務(wù)器來說搞动,這是一個(gè)非常好的主意躏精,因?yàn)楣粽呓?jīng)常在所有服務(wù)器上嘗試隨機(jī)帳戶名和密碼并希望能中獎(jiǎng)。 要禁用密碼登錄滋尉,請(qǐng)?jiān)?em>/etc/ssh/sshd_config中更改以下行:
/etc/ssh/sshd_config:禁用密碼登錄玉控。
PasswordAuthentication no
完成編輯SSH配置后飞主,需要重新啟動(dòng)ssh服務(wù)以使更改生效:
$ sudo service ssh restart
我要做的第三個(gè)改變是安裝防火墻狮惜。 這是一個(gè)阻止在任何未明確啟用的端口上訪問服務(wù)器的軟件:
$ sudo apt-get install -y ufw
$ sudo ufw allow ssh
$ sudo ufw allow http
$ sudo ufw allow 443/tcp
$ sudo ufw --force enable
$ sudo ufw status
這些命令會(huì)安裝ufw(簡單防火墻)高诺,并將其配置為僅允許端口22(ssh),80(http)和443(https)上的外部通信碾篡。 任何其他端口將不被允許虱而。
安裝基礎(chǔ)依賴
如果你遵循了我的建議并配置了Ubuntu 16.04發(fā)行版的服務(wù)器,那么你的系統(tǒng)完全支持Python 3.5开泽,因此這是我將用于部署的Python版本牡拇。
基礎(chǔ)的Python解釋器可能已經(jīng)預(yù)先安裝在你的服務(wù)器上,但有一些額外的軟件包可能卻沒有穆律,而且Python之外還有一些其他軟件包可用于創(chuàng)建健壯的生產(chǎn)環(huán)境部署惠呼。 對(duì)于數(shù)據(jù)庫服務(wù)器,我將從SQLite切換到MySQL峦耘。 Postfix包是一個(gè)郵件傳輸代理剔蹋,我將用它來發(fā)送電子郵件。 Supervisor工具將監(jiān)視Flask服務(wù)器進(jìn)程辅髓,并在其崩潰時(shí)自動(dòng)重啟泣崩,并當(dāng)Supervisor服務(wù)重啟后自動(dòng)啟動(dòng)其監(jiān)視的服務(wù)。 Nginx服務(wù)器將接受來自外部世界的所有請(qǐng)求洛口,并將它們轉(zhuǎn)發(fā)給應(yīng)用程序矫付。 最后,我將使用git來從git倉庫下載應(yīng)用程序第焰。
$ sudo apt-get -y update
$ sudo apt-get -y install python3 python3-venv python3-dev
$ sudo apt-get -y install mysql-server postfix supervisor nginx git
這些安裝大部分是無人值守的买优,但是在運(yùn)行第三條安裝語句到一定進(jìn)度時(shí),系統(tǒng)會(huì)提示你為MySQL服務(wù)選擇一個(gè)root密碼挺举,并且還會(huì)詢問關(guān)于安裝postfix軟件包的一些問題而叼,你可以接受他們的默認(rèn)答案。
請(qǐng)注意豹悬,對(duì)于此部署葵陵,我選擇不安裝Elasticsearch。 這項(xiàng)服務(wù)需要大量的RAM瞻佛,所以只有擁有超過2GB內(nèi)存的大型服務(wù)器時(shí)才可以考慮脱篙。 為了避免服務(wù)器內(nèi)存不足的問題,我將停用搜索功能伤柄。 如果你有高配的服務(wù)器绊困,可以從Elasticsearch站點(diǎn)下載官方的.deb軟件包,并按照其安裝說明將其添加到你的服務(wù)器适刀。 請(qǐng)注意秤朗,Ubuntu 16.04軟件包存儲(chǔ)庫中提供的Elasticsearch軟件包太舊,無法運(yùn)行笔喉,你需要6.x或更高版本取视。
我還注意到硝皂,默認(rèn)安裝的postfix可能不足以在生產(chǎn)環(huán)境中發(fā)送電子郵件。 為了避免垃圾郵件和惡意郵件作谭,很多服務(wù)器都要求發(fā)件人服務(wù)器通過安全擴(kuò)展標(biāo)識(shí)自己稽物,這意味著至少你必須擁有與你的服務(wù)器相關(guān)聯(lián)的域名。 如果你想了解如何完全配置電子郵件服務(wù)器以使其通過標(biāo)準(zhǔn)安全測試折欠,請(qǐng)參閱以下Digital Ocean的指南:
安裝應(yīng)用
現(xiàn)在我要使用git
從我的GitHub代碼庫下載Microblog源代碼贝或。 如果你不熟悉git源碼控制,我建議你閱讀git for beginners锐秦。
要將應(yīng)用下載到服務(wù)器咪奖,請(qǐng)確保你位于ubuntu
用戶的主目錄中,然后運(yùn)行:
$ git clone https://github.com/miguelgrinberg/microblog
$ cd microblog
$ git checkout v0.17
這會(huì)將代碼克隆到你的服務(wù)器上酱床,并將其同步到本章的內(nèi)容赡艰。 如果你在學(xué)習(xí)本教程的過程中維護(hù)了自己的git代碼庫,則可以將代碼庫URL更改為你的URL斤葱,在這種情況下慷垮,你可以跳過git checkout
命令。
現(xiàn)在我需要?jiǎng)?chuàng)建一個(gè)虛擬環(huán)境并使用所有的包依賴項(xiàng)來填充它揍堕,在第十五章中料身,我已將依賴包的列表保存到requirements.txt文件中:
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install -r requirements.txt
除了requirements.txt中的包之外,我還將使用此生產(chǎn)部署指定的兩個(gè)包衩茸,因此它們不包含在requirements.txt文件中芹血。 gunicorn
軟件包是Python應(yīng)用程序的生產(chǎn)Web服務(wù)器。 pymysql
軟件包包含MySQL驅(qū)動(dòng)程序楞慈,它使SQLAlchemy能夠與MySQL數(shù)據(jù)庫一起工作:
(venv) $ pip install gunicorn pymysql
我需要?jiǎng)?chuàng)建一個(gè).env文件幔烛,其中包含所有需要的環(huán)境變量:
/home/ubuntu/microblog/.env:環(huán)境配置。
SECRET_KEY=52cb883e323b48d78a0a36e8e951ba4a
MAIL_SERVER=localhost
MAIL_PORT=25
DATABASE_URL=mysql+pymysql://microblog:<db-password>@localhost:3306/microblog
MS_TRANSLATOR_KEY=<your-translator-key-here>
這個(gè).env文件與我在第十五章展示的非常類似囊蓝,但是我為SECRET_KEY使用了一個(gè)隨機(jī)字符串饿悬。 為了生成這個(gè)隨機(jī)字符串,我使用了下面的命令:
python3 -c "import uuid; print(uuid.uuid4().hex)
對(duì)于DATABASE_URL
變量聚霜,我定義了一個(gè)MySQL URL狡恬。 我將在下一節(jié)中向你介紹如何配置數(shù)據(jù)庫。
我需要將FLASK_APP
環(huán)境變量設(shè)置為應(yīng)用程序的入口點(diǎn)以啟用flask
命令蝎宇,但在解析.env文件之前需要此變量弟劲,因此需要手動(dòng)設(shè)置。 為避免每次都設(shè)置它姥芥,我把它添加到ubuntu
帳戶的~/.profile文件的底部兔乞,以便每次登錄時(shí)自動(dòng)設(shè)置它:
$ echo "export FLASK_APP=microblog.py" >> ~/.profile
如果你注銷并重新登錄,現(xiàn)在FLASK_APP
就已經(jīng)設(shè)置好了。 你可以通過運(yùn)行flask --help
來確認(rèn)它是否已經(jīng)設(shè)置好了庸追。 如果幫助信息顯示應(yīng)用程序已添加的translate
命令霍骄,那么你就知道應(yīng)用程序已被找到。
現(xiàn)在flask
命令是有效的锚国,我可以編譯語言翻譯:
(venv) $ flask translate compile
設(shè)置MySQL
我在開發(fā)過程中使用過的sqlite數(shù)據(jù)庫非常適合簡單的應(yīng)用程序腕巡,但是當(dāng)部署可能需要一次處理多個(gè)請(qǐng)求的健壯Web服務(wù)器時(shí)玄坦,最好使用更強(qiáng)大的數(shù)據(jù)庫血筑。 出于這個(gè)原因,我要建立一個(gè)名為’microblog’的MySQL數(shù)據(jù)庫煎楣。
要管理數(shù)據(jù)庫服務(wù)器豺总,我將使用mysql
命令斯入,該命令應(yīng)該已經(jīng)安裝在你的服務(wù)器上:
$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.19-0ubuntu0.16.04.1 (Ubuntu)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
請(qǐng)注意沟启,你需要鍵入你在安裝MySQL時(shí)選擇的MySQL root密碼才能訪問MySQL命令提示符肚菠。
這些是創(chuàng)建名為microblog
的新數(shù)據(jù)庫的命令冒滩,以及具有完全訪問權(quán)限的同名用戶:
mysql> create database microblog character set utf8 collate utf8_bin;
mysql> create user 'microblog'@'localhost' identified by '<db-password>';
mysql> grant all privileges on microblog.* to 'microblog'@'localhost';
mysql> flush privileges;
mysql> quit;
你將需要用你選擇的密碼來替換<db-password>
跟畅。 這將是microblog
數(shù)據(jù)庫用戶的密碼概而,所以不要使用你已為root用戶選擇的密碼迄沫。 microblog
用戶的密碼需要與你包含在.env文件中的DATABASE_URL
變量中的密碼相匹配憎蛤。
如果你的數(shù)據(jù)庫配置是正確的慷丽,你現(xiàn)在應(yīng)該能夠運(yùn)行數(shù)據(jù)庫遷移以創(chuàng)建所有的表:
(venv) $ flask db upgrade
繼續(xù)下一步之前蹦哼,確保上述命令成功完成且不會(huì)產(chǎn)生任何錯(cuò)誤。
設(shè)置Gunicorn和Supervisor
當(dāng)你使用flask run
運(yùn)行服務(wù)器時(shí)要糊,正在使用的是Flask附帶的Web服務(wù)器纲熏。 該服務(wù)器在開發(fā)過程中非常有用,但它不適合用于生產(chǎn)服務(wù)器锄俄,因?yàn)樗豢紤]性能和穩(wěn)健性局劲。 取而代之,我決定使用gunicorn奶赠,它是一個(gè)純粹的Python Web服務(wù)器鱼填,但與Flask不同,它是一個(gè)支持高并發(fā)的強(qiáng)大生產(chǎn)服務(wù)器毅戈,同時(shí)它也非常容易使用剔氏。
要在gunicorn下啟動(dòng)Microblog,你可以使用以下命令:
(venv) $ gunicorn -b localhost:8000 -w 4 microblog:app
-b
選項(xiàng)告訴gunicorn在哪里監(jiān)聽請(qǐng)求竹祷,我在8000端口上監(jiān)聽了內(nèi)部網(wǎng)絡(luò)接口谈跛。 在沒有外部訪問的情況下運(yùn)行Python Web應(yīng)用程序通常是一個(gè)好主意,然后還需要一個(gè)非乘芰辏快速的Web服務(wù)器感憾,它可以優(yōu)化來自客戶端的所有靜態(tài)文件的請(qǐng)求。 這個(gè)快速的Web服務(wù)器將直接提供靜態(tài)文件,并將用于應(yīng)用程序的任何請(qǐng)求轉(zhuǎn)發(fā)到內(nèi)部服務(wù)器阻桅。 我將在下一節(jié)中向你展示如何將nginx設(shè)置為面向公眾的服務(wù)器凉倚。
-w
選項(xiàng)配置gunicorn將運(yùn)行多少worker。 擁有四個(gè)進(jìn)程可以讓應(yīng)用程序同時(shí)處理多達(dá)四個(gè)客戶端嫂沉,這對(duì)于Web應(yīng)用程序通常足以處理大量客戶端請(qǐng)求稽寒,因?yàn)椴⒎撬锌蛻舳硕荚诓粩嗾?qǐng)求內(nèi)容。 根據(jù)服務(wù)器的RAM大小趟章,你可能需要調(diào)整worker數(shù)量杏糙,以免內(nèi)存不足。
microblog:app
參數(shù)告訴gunicorn如何加載應(yīng)用程序?qū)嵗?冒號(hào)前的名稱是包含應(yīng)用程序的模塊蚓土,冒號(hào)后面的名稱是此應(yīng)用程序的名稱宏侍。
雖然gunicorn的設(shè)置非常簡單,但從命令行運(yùn)行服務(wù)器在生產(chǎn)服務(wù)器實(shí)際上不是一個(gè)恰當(dāng)?shù)姆桨浮?我想要做的是讓服務(wù)器在后臺(tái)運(yùn)行蜀漆,并持續(xù)監(jiān)視谅河,因?yàn)槿绻捎谀撤N原因?qū)е路?wù)器崩潰并退出,我想確保新的服務(wù)器自動(dòng)啟動(dòng)以取代它确丢。 而且我還想確保如果機(jī)器重新啟動(dòng)绷耍,服務(wù)器在啟動(dòng)時(shí)自動(dòng)運(yùn)行,而無需人工登錄和啟動(dòng)鲜侥。 我將使用上面安裝的supervisor包來執(zhí)行此操作褂始。
Supervisor使用配置文件定義它要監(jiān)視什么程序以及如何在必要時(shí)重新啟動(dòng)它們。 配置文件必須存儲(chǔ)在/etc/supervisor/conf.d中剃毒。 這是Microblog的配置文件病袄,我將其稱為microblog.conf:
/etc/supervisor/conf.d/microblog.conf:Supervisor配置。
[program:microblog]
command=/home/ubuntu/microblog/venv/bin/gunicorn -b localhost:8000 -w 4 microblog:app
directory=/home/ubuntu/microblog
user=ubuntu
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
command
赘阀,directory
和user
設(shè)置告訴supervisor如何運(yùn)行應(yīng)用程序益缠。 如果計(jì)算機(jī)啟動(dòng)或崩潰,autostart
和autorestart
設(shè)置會(huì)使microblog自動(dòng)重新啟動(dòng)基公。 stopasgroup
和killasgroup
選項(xiàng)確保當(dāng)supervisor需要停止應(yīng)用程序來重新啟動(dòng)它時(shí)幅慌,它仍然會(huì)調(diào)度成頂級(jí)gunicorn進(jìn)程的子進(jìn)程。
編寫此配置文件后轰豆,必須重載supervisor服務(wù)的配置才能導(dǎo)入它:
$ sudo supervisorctl reload
像這樣胰伍,這個(gè)gunicorn web服務(wù)器就已經(jīng)啟動(dòng)和運(yùn)行,并處于監(jiān)控之中酸休!
設(shè)置Nginx
由gunicorn啟動(dòng)的microblog應(yīng)用服務(wù)器現(xiàn)在運(yùn)行在本地端口8000骂租。 我現(xiàn)在需要做的是將應(yīng)用程序暴露給外部世界,為了使面向公眾的web服務(wù)器能夠被訪問斑司,我在防火墻上打開了兩個(gè)端口(80和443)來處理應(yīng)用程序的Web通信渗饮。
我希望這是一個(gè)安全的部署,所以我要配置端口80將所有流量轉(zhuǎn)發(fā)到將要加密的端口443。 我將首先創(chuàng)建一個(gè)SSL證書互站。創(chuàng)建一個(gè)自簽名SSL證書私蕾,這對(duì)于測試是可以的,但對(duì)于真正的部署不太好胡桃,因?yàn)閃eb瀏覽器會(huì)警告用戶踩叭,證書不是由可信證書頒發(fā)機(jī)構(gòu)頒發(fā)的。 創(chuàng)建microblog的SSL證書的命令是:
$ mkdir certs
$ openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
-keyout certs/key.pem -out certs/cert.pem
該命令將要求你提供關(guān)于應(yīng)用程序和你自己的一些信息翠胰。 這些信息將包含在SSL證書中容贝,如果用戶請(qǐng)求查看它,Web瀏覽器則會(huì)向用戶顯示它們亡容。上述命令的結(jié)果將是名為key.pem和cert.pem的兩個(gè)文件嗤疯,我將其放置在Microblog根目錄的certs子目錄中冤今。
要有一個(gè)由nginx服務(wù)的網(wǎng)站闺兢,你需要為它編寫配置文件。 在大多數(shù)nginx安裝中戏罢,這個(gè)文件需要位于/etc/nginx/sites-enabled目錄中屋谭。Nginx在這個(gè)位置安裝了一個(gè)我不需要的測試站點(diǎn),所以我將首先刪除它:
$ sudo rm /etc/nginx/sites-enabled/default
下面你可以看到Microblog的nginx配置文件龟糕,它在/etc/nginx/sites-enabled/microblog中:
/etc/nginx/sites-enabled/microblog:Nginx配置桐磁。
server {
# listen on port 80 (http)
listen 80;
server_name _;
location / {
# redirect any requests to the same URL but on https
return 301 https://$host$request_uri;
}
}
server {
# listen on port 443 (https)
listen 443 ssl;
server_name _;
# location of the self-signed SSL certificate
ssl_certificate /home/ubuntu/microblog/certs/cert.pem;
ssl_certificate_key /home/ubuntu/microblog/certs/key.pem;
# write access and error logs to /var/log
access_log /var/log/microblog_access.log;
error_log /var/log/microblog_error.log;
location / {
# forward application requests to the gunicorn server
proxy_pass http://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
# handle static files directly, without forwarding to the application
alias /home/ubuntu/microblog/static;
expires 30d;
}
}
Nginx的配置不易理解,但我添加了一些注釋讲岁,至少你可以知道每個(gè)部分的功能我擂。 如果你想獲得關(guān)于特定指令的信息,請(qǐng)參閱nginx官方文檔缓艳。
添加此文件后校摩,你需要告訴nginx重新加載配置以激活它:
$ sudo service nginx reload
現(xiàn)在應(yīng)用程序應(yīng)該部署成功了。 在你的Web瀏覽器中阶淘,可以鍵入服務(wù)器的IP地址(如果使用的是Vagrant VM衙吩,則為192.168.33.10),然后該服務(wù)器將連接到應(yīng)用程序溪窒。 由于你使用的是自簽名證書坤塞,因此將收到來自Web瀏覽器的警告,你必須解除該警告澈蚌。
使用上述說明為自己的項(xiàng)目完成部署之后摹芙,我強(qiáng)烈建議你將自簽名證書替換為真實(shí)的證書,以便瀏覽器不會(huì)在用戶訪問你的網(wǎng)站時(shí)發(fā)出警告宛瞄。 為此浮禾,你首先需要購買域名并將其配置為指向你的服務(wù)器的IP地址。 一旦你有一個(gè)域名,你可以申請(qǐng)一個(gè)免費(fèi)的Let’s Encrypt SSL證書伐厌。 我在博客上寫了一篇關(guān)于如何通過HTTPS運(yùn)行你的Flask應(yīng)用程序的詳細(xì)文章承绸。
部署應(yīng)用更新
我想討論的基于Linux的部署的最后一個(gè)主題是如何處理應(yīng)用程序升級(jí)。 應(yīng)用程序源代碼通過git
安裝在服務(wù)器中挣轨,因此军熏,無論何時(shí)想要將應(yīng)用程序升級(jí)到最新版本,都可以運(yùn)行git pull
來下載自上次部署以來的新提交卷扮。
當(dāng)然荡澎,下載新版本的代碼不會(huì)導(dǎo)致升級(jí)。 當(dāng)前正在運(yùn)行的服務(wù)器進(jìn)程將繼續(xù)運(yùn)行晤锹,舊代碼已被讀取并存儲(chǔ)在內(nèi)存中摩幔。 要觸發(fā)升級(jí),你必須停止當(dāng)前的服務(wù)器并啟動(dòng)一個(gè)新的服務(wù)器鞭铆,以強(qiáng)制重新讀取所有代碼或衡。
進(jìn)行升級(jí)通常比重新啟動(dòng)服務(wù)器更為復(fù)雜。 你可能需要應(yīng)用數(shù)據(jù)庫遷移或編譯新的語言翻譯车遂,因此實(shí)際上封断,執(zhí)行升級(jí)的過程涉及一系列命令:
(venv) $ git pull # download the new version
(venv) $ sudo supervisorctl stop microblog # stop the current server
(venv) $ flask db upgrade # upgrade the database
(venv) $ flask translate compile # upgrade the translations
(venv) $ sudo supervisorctl start microblog # start a new server
樹莓派托管
樹莓派是一款革命性低成本的小型Linux計(jì)算機(jī),功耗非常低舶担,因此它是托管家庭在線服務(wù)器的理想設(shè)備坡疼,可以全天候在線而無需捆綁你的臺(tái)式電腦或筆記本電腦。 有幾個(gè)Linux發(fā)行版可以在樹莓派上運(yùn)行衣陶。 我的選擇是Raspbian柄瑰,這是樹莓派基金會(huì)的官方發(fā)行版。
為了準(zhǔn)備樹莓派的環(huán)境剪况,我要安裝一個(gè)新的Raspbian版本教沾。 我將使用2017年9月版的Raspbian Stretch Lite,但在閱讀本文時(shí)拯欧,可能會(huì)有更新的版本详囤,請(qǐng)查看官方下載頁面獲得最新版本。
Raspbian鏡像需要安裝在SD卡上镐作,然后插入樹莓派藏姐,以便它啟動(dòng)時(shí)可以識(shí)別到。 在樹莓派站點(diǎn)上可以查看到從Windows该贾,Mac OS X和Linux將Raspbian鏡像復(fù)制到SD卡的方法羔杨。
當(dāng)你第一次啟動(dòng)樹莓派時(shí),請(qǐng)?jiān)谶B接到鍵盤和顯示器時(shí)進(jìn)行操作杨蛋,以便你可以進(jìn)行設(shè)置兜材。 至少應(yīng)該啟用SSH理澎,以便你可以從計(jì)算機(jī)登錄并方便地執(zhí)行部署任務(wù)。
和Ubuntu一樣曙寡,Raspbian也是Debian的衍生產(chǎn)品糠爬,所以上面針對(duì)的Ubuntu Linux的說明,大部分都可以在樹莓派上生效举庶。 但是执隧,如果你計(jì)劃在家庭網(wǎng)絡(luò)上運(yùn)行小型應(yīng)用程序而無需外部訪問時(shí),則可以跳過某些步驟户侥。 例如镀琉,你可能不需要防火墻或無密碼登錄。 你可能想在這樣一臺(tái)小型的計(jì)算機(jī)上使用SQLite而不是MySQL蕊唐。 你可以選擇不使用nginx屋摔,并且讓gunicorn服務(wù)器直接監(jiān)聽來自客戶端的請(qǐng)求。 你可能只想要一個(gè)gunicorn worker進(jìn)程替梨。 Supervisor服務(wù)對(duì)于確保應(yīng)用程序始終處于運(yùn)行狀態(tài)非常有用钓试,因此我建議你仍然在樹莓派上使用它。