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 地址,就可以看到

到這裏 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

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

您可能感興趣的文章:

原文鏈接:http://blog.adisonhyh.com/article/2/

發佈了13 篇原創文章 · 獲贊 25 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章