天天看點

centos flask gunicorn 伺服器部署

最近在學習 python,使用 flask 實作了個個人部落格程式,完了想部署到伺服器上。因為是新手,一路磕磕絆絆最終把它基本搞定。網上資料對新手感覺都不太友好,都是零零碎碎的,是以我整理了一下,一方面作為我自己的記錄,友善以後查閱,另一方面也希望能幫助到跟我一樣的新手。

前提

  1. 有一個伺服器(不然搞毛),購買可以參考優質國外vps推薦
  2. 有個人域名(當然,你可以直接使用 IP通路,但有點奇怪不是?購買域名可以去GoDaddy

1.安裝git

可以選擇 github 或者Bitbucket,當然你也可以自己搭建 git伺服器,但我覺得沒啥必要,我選擇Bitbucket,主要是因為它私有庫免費

?

1

sudo

yum

install

git

後續就跟我們本地開發沒什麼差別了,配置 ssh key,clone代碼,就不展開了,項目目錄建議放在 /home/www/ 下

2. 安裝 Mysql

添加 MySQL YUM 源

?

1

2

3

4

5

6

7

$wget

'https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm'

$

sudo

rpm -Uvh mysql57-community-release-el7-11.noarch.rpm

$yum repolist all |

grep

mysql

mysql-connectors-community

/x86_64

MySQL Connectors Community         36

mysql-tools-community

/x86_64

MySQL Tools Community            47

mysql57-community

/x86_64

MySQL 5.7 Community Server         187

安裝最新版本

?

1

$

sudo

yum

install

mysql-community-server

啟動 MySQL 服務

?

1

2

3

4

5

6

7

8

9

10

11

12

$sudo service mysqld start

$sudo systemctl start mysqld #CentOS 7

$sudo systemctl status mysqld

● mysqld.service - MySQL Community Server

Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)

Active: active (running) since Sat 2017-05-27 12:56:26 CST; 15s ago

Process: 2482 ExecStartPost=/usr/bin/mysql-systemd-start post (code=exited, status=0/SUCCESS)

Process: 2421 ExecStartPre=/usr/bin/mysql-systemd-start pre (code=exited, status=0/SUCCESS)

Main PID: 2481 (mysqld_safe)

CGroup: /system.slice/mysqld.service

├─2481 /bin/sh /usr/bin/mysqld_safe --basedir=/usr

└─2647 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/...

說明已經正在運作中了

修改密碼

?

1

$ mysql -uroot -p

這裡有要求你輸入密碼,Mysql安裝時會生成一個預設密碼,使用 grep "temporary password" /var/log/mysqld.log 指令,傳回結果最後引号後面的字元串就是root的預設密碼

?

1

mysql>

ALTER

USER

'root'

@

'localhost'

IDENTIFIED

BY

'NewPassword'

;

修改編碼

在 /etc/my.cnf 中設定預設的編碼

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

[client]

default-character-set = utf8

[mysqld]

default-storage-engine = INNODB

character-set-server = utf8

collation-server = utf8_general_ci #不區分大小寫

collation-server = utf8_bin #區分大小寫

collation-server = utf8_unicode_ci #比 utf8_general_ci 更準确

建立資料庫

?

1

mysql>

CREATE

DATABASE

<datebasename>

CHARACTER

SET

utf8;

3. 安裝python3 pip3

CentOS 7 預設安裝了 Python 2,當需要使用 Python 3 的時候,可以手動下載下傳 Python 源碼後編譯安裝。

安裝 Python 3

?

1

2

3

4

5

6

7

8

sudo

mkdir

/usr/local/python3

# 建立安裝目錄

$ wget --no-check-certificate https:

//www

.python.org

/ftp/python/3

.6.2

/Python-3

.6.2.tgz

# 下載下傳 Python 源檔案

# 注意:wget擷取https的時候要加上:--no-check-certifica

$

tar

-xzvf Python-3.6.2.tgz

# 解壓縮包

$

cd

Python-3.6.2

# 進入解壓目錄

sudo

.

/configure

--prefix=

/usr/local/python3

# 指定建立的目錄

sudo

make

sudo

make

install

# 編譯安裝

執行./configure時可能會報錯,configure: error: no acceptable C compiler found in $PATH,這是因為未安裝合适的編譯器,安裝下就好了,

sudo yum install gcc-c++ (使用sudo yum install gcc-c++時會自動安裝/更新gcc及其他依賴的包。)

配置兩個版本共存

建立 python3 的軟連結:

?

1

$

sudo

ln

-s

/usr/local/python3/bin/python3

/usr/bin/python3

這樣就可以通過 python 指令使用 Python 2, python3 來使用 Python 3。

安裝 pip

?

1

2

3

$

sudo

yum -y

install

epel-release

# 首先安裝 epel 擴充源

$

sudo

yum -y

install

python-pip

# 安裝 python-pip

$

sudo

yum clean all

# 清除 cache

通過這種方式貌似隻能安裝 pip2,想要安裝 Python 3 的 pip,可以通過以下的源代碼安裝方式。

?

1

2

3

4

5

6

7

8

# 下載下傳源代碼

$ wget --no-check-certificate https:

//github

.com

/pypa/pip/archive/9

.0.1.

tar

.gz

$

tar

-zvxf 9.0.1.

tar

.gz 

# 解壓檔案

$

cd

pip-9.0.1

$ python3 setup.py

install

# 使用 Python 3 安裝

建立連結:

?

1

$

sudo

ln

-s

/usr/local/python3/bin/pip

/usr/bin/pip3

更新 pip

?

1

$ pip

install

--upgrade pip

4. 安裝 gunicorn

Gunicorn (獨角獸)是一個高效的Python WSGI Server,通常用它來運作 wsgi application(由我們自己編寫遵循WSGI application的編寫規範) 或者 wsgi framework(如Django,Paster),地位相當于Java中的Tomcat。 WSGI就是這樣的一個協定:它是一個Python程式和使用者請求之間的接口。WSGI伺服器的作用就是接受并分析使用者的請求,調用相應的python對象完成對請求的處理,然後傳回相應的結果。 簡單來說gunicorn封裝了HTTP的底層實作,我們通過gunicorn啟動服務,使用者請求與服務相應都經過gunicorn傳輸

建立虛拟環境

?

1

2

3

cd

/home/www/blog

mkdir

venv

python3 -m venv venv

激活虛拟環境:

?

1

source venv/bin/activate

然後根據 requirements.txt 檔案安裝依賴包:

?

1

pip3 install

-

r requirements.txt

安裝gunicorn

?

1

pip3 install gunicorn

在項目根目錄建立一個wsgi.py檔案

?

1

2

3

4

5

6

from

app

import

create_app

application

=

create_app(

'production'

)

if

__name__

=

=

'__main__'

:

application.run()

不再通過manage.py啟動服務,那隻在開發的時候使用

啟動服務:

?

1

gunicorn -w 4 -b 127.0.0.1:8000 wsgi:application

5. 安裝 Nginx

nginx 是一個高性能的web伺服器。通常用來在前端做反向代理伺服器。所謂正向與反向(reverse),隻是英文說法翻譯。代理服務,簡而言之,一個請求經過代理伺服器從區域網路發出,然後到達網際網路上伺服器,這個過程的代理為正向代理。如果一個請求,從網際網路過來,先進入代理伺服器,再由代理伺服器轉發給區域網路的目标伺服器,這個時候,代理伺服器為反向代理(相對正向而言)。

正向代理:{ 用戶端 ---》 代理伺服器 } ---》 伺服器

反向代理:用戶端 ---》 { 代理伺服器 ---》 伺服器 }

{} 表示區域網路

nginx既可以做正向,也可以做反向。

?

1

$ yum -y

install

nginx

啟動 nginx 服務

?

1

$ service nginx start

停止 nginx 服務

?

1

$ service nginx stop

重新開機 nginx 服務

?

1

$ service nginx restart

平滑重新開機

nginx配置改動了,可以重新加載而不用先關閉再打開

?

1

$ nginx -s reload

啟動後 ,在浏覽器中 輸入伺服器的 ip 位址,就可以看到

centos flask gunicorn 伺服器部署

到這裡 yum 安裝 nginx 就完成了

添加配置

nginx的配置檔案為: /etc/nginx/nginx.conf

?

1

2

3

4

5

6

7

8

9

10

server {

listen 80;

server_name adisonhyh.com;

location / {

proxy_pass http:

//127

.0.0.1:8000;

proxy_set_header Host $host;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

  1. 監聽http預設的端口号80
  2. server_name:個人網站域名
  3. 把請求代理到本機的8000端口(gunicorn啟動服務指定的端口) 剩下proxy_set_header照抄

gunicorn和nginx關系:

gunicorn 可以單獨提供服務,但生産環境一般不這樣做。首先靜态資源(jscssimg)會占用不少的請求資源,而對于 gunicorn 來講它本身更應該關注實際業務的請求與處理而不應該把資源浪費在靜态資源請求上;此外,單獨運作 gunicorn 是沒有辦法起多個程序多個端口來負載均衡的。

nginx 的作用就是彌補以上問題,首先作為前端伺服器它可以處理一切靜态檔案請求,此時 gunicorn 作為後端伺服器,nginx 将會把動态請求轉發給後端伺服器,是以我們可以起多個 gunicorn 程序,然後讓 nginx 作均衡負載轉發請求給多個 gunicorn 程序進而提升伺服器處理效率與處理能力。最後,nginx 還可以配置很多安全相關、認證相關等很多處理,可以讓你的網站更專注業務的編寫,把一些轉發規則等其它業務無關的事情交給 nginx 做。

配置好後打開本地浏覽器,輸入域名,應該就能通路了。

6.supervisor

如果你需要程序一直執行,若該程序因各種原因中斷,也會自動重新開機的話,supervisor是一個很好的選擇。 supervisor管理程序,是通過fork/exec的方式将這些被管理的程序當作supervisor的子程序來啟動,是以我們隻需要将要管理程序的可執行檔案的路徑添加到supervisor的配置檔案中就好了。此時被管理程序被視為supervisor的子程序,若該子程序異常終端,則父程序可以準确的擷取子程序異常終端的資訊,通過在配置檔案中設定autostart=true,可以實作對異常中斷的子程序的自動重新開機。

安裝 supervisor

?

1

2

3

$ pip install supervisor

$ echo_supervisord_conf > supervisor.conf  # 生成 supervisor 預設配置檔案

$ vim supervisor.conf            # 修改 supervisor 配置檔案,添加 gunicorn 程序管理

在blog supervisor.conf 配置檔案底部添加 (注意我的工作路徑是 www/home/blog/ )

?

1

2

3

4

5

6

7

8

9

[program:blog]

command=/home/www/blog/venv/bin/gunicorn -w4 -b0.0.0.0:8000 wsgi:application  ;supervisor啟動指令

directory=/home/www/blog                         ; 項目的檔案夾路徑

startsecs=0                                ; 啟動時間

stopwaitsecs=0                              ; 終止等待時間

autostart=false                              ; 是否自動啟動

autorestart=false                             ; 是否自動重新開機

stdout_logfile=/home/www/blog/logs/gunicorn.log              ; log 日志

stderr_logfile=/home/www/blog/logs/gunicorn.err              ; 錯誤日志

使用 supervsior 啟動 gunicorn

?

1

2

$

sudo

supervisord -c supervisor.conf

$

sudo

supervisorctl start blog

在浏覽器位址欄輸入配置的位址即可通路網站。

7. fabric

最後一步,我們使用fabric實作遠端操作和部署。Fabric 是一個 Python 下類似于 Makefiles 的工具,但是能夠在遠端伺服器上執行指令。

安裝 fabric

?

1

pip install fabric

在 blog 目錄下建立一個fabfile.py檔案

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

import

os

from

fabric.api

import

local, env, run, cd, sudo, prefix, settings, execute, task, put

from

fabric.contrib.files

import

exists

from

contextlib

import

contextmanager

env.hosts

=

[

'204.152.201.69'

]

env.user

=

'root'

env.password

=

'****'

#密碼

env.group

=

"root"

DEPLOY_DIR

=

'/home/www/blog'

VENV_DIR

=

os.path.join(DEPLOY_DIR,

'venv'

)

VENV_PATH

=

os.path.join(VENV_DIR,

'bin/activate'

)

@contextmanager

def

source_virtualenv():

with prefix(

"source {}"

.

format

(VENV_PATH)):

yield

def

update():

with cd(

'/home/www/blog/'

):

sudo(

'git pull'

)

def

restart():

with cd(DEPLOY_DIR):

if

not

exists(VENV_DIR):

run(

"virtualenv {}"

.

format

(VENV_DIR))

with settings(warn_only

=

True

):

with source_virtualenv():

run(

"pip install -r {}/requirements.txt"

.

format

(DEPLOY_DIR))

with settings(warn_only

=

True

):

stop_result

=

sudo(

"supervisorctl -c {}/supervisor.conf stop all"

.

format

(DEPLOY_DIR))

if

not

stop_result.failed:

kill_result

=

sudo(

"pkill supervisor"

)

if

not

kill_result:

sudo(

"supervisord -c {}/supervisor.conf"

.

format

(DEPLOY_DIR))

sudo(

"supervisorctl -c {}/supervisor.conf reload"

.

format

(DEPLOY_DIR))

sudo(

"supervisorctl -c {}/supervisor.conf status"

.

format

(DEPLOY_DIR))

sudo(

"supervisorctl -c {}/supervisor.conf start all"

.

format

(DEPLOY_DIR))

@task

def

deploy():

execute(update)

execute(restart)

現在代碼如果更新了,可以直接在本地執行遠端部署了

?

1

fab deploy

以上就是本文的全部内容,希望對大家的學習有所幫助,也希望大家多多支援腳本之家。

您可能感興趣的文章:

  • 淺談flask中的before_request與after_request
  • flask中使用藍圖将路由分開寫在不同檔案執行個體解析
  • flask使用session儲存登入狀态及攔截未登入請求代碼
  • flask中主動抛出異常及統一異常處理代碼示例
  • Vue+Flask實作簡單的登入驗證跳轉的示例代碼
  • centos 7.0 使用Nginx部署flask應用教程
  • python Flask實作restful api service
  • Flask實作異步非阻塞請求功能執行個體解析

原文連結:http://blog.adisonhyh.com/article/2/

繼續閱讀