封尘网

让学习成为一种习惯!

Centos7 安装Python3.6+Nginx+Gunicorn+Flask

Centos7 安装Python3.6+Nginx+Gunicorn Flask

最近阿里云服务器到期了,而续费又太贵了,不得已再买过一台新的。同也打算把博客迁移到Python环境中运行。所以先在测试环境中试验一下效果。

安装一些常用依赖包:

yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make

1、下载Python3.6.4并安装到系统中

wget https://www.python.org/ftp/python/3.6.4/Python-3.6.4.tgz 
tar xf Python-3.6.4.tgz 
cd Python-3.6.4 
./configure --prefix=/opt/py36 --enable-optimizations 
make && make install 


Collecting setuptools

Collecting pip

Installing collected packages: setuptools, pip

Successfully installed pip-9.0.1 setuptools-28.8.0

验证是否安装成功:

[root@docker Python-3.6.4]# /opt/py36/bin/pip3 list 

DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.

出现这个提示可以修改配置文件或者直接添加参数:--format=(columns|legacy)

[root@docker Python-3.6.4]# /opt/py36/bin/pip3 list --format=columns 
Package    Version 
---------- ------- 
pip        9.0.1   
setuptools 28.8.0

通过配置文件方式:在用户的家目录下创建一个目录:

[root@docker py36]# mkdir ~/.pip 
[root@docker py36]# cat >~/.pip/pip.conf <<EOF 
> [list] 
> format=columns 
> EOF

2、为了方便直接yum安装nginx [前提是要有epel源]

yum install nginx -y

添加到开机启动:

systemctl enable nginx 
systemctl start nginx

检查是否成功运行Nginx:

[root@docker yum.repos.d]# curl -I http://127.0.0.1

3、通过pip3安装相关的插件

[root@docker bin]# /opt/py36/bin/pip3 install virtualenv 

Collecting virtualenv 

  Could not fetch URL https://pypi.python.org/simple/virtualenv/: There was a problem confirming the ssl certificate: Can't connect to HTTPS URL because the SSL module is not available. - skipping 

  Could not find a version that satisfies the requirement virtualenv (from versions: ) 

No matching distribution found for virtualenv

如果出现这样的情况,肯定是在编译Python3.6.4的时候,系统并没有安装上openssl-devel包;

解决办法:

yum install openssl-devel -y

再重新编译安装Python即可。

root@docker Python-3.6.4]# /opt/py36/bin/pip3 install virtualenv 
Collecting virtualenv 

  Downloading virtualenv-15.1.0-py2.py3-none-any.whl (1.8MB) 

    100% |████████████████████████████████| 1.8MB 22kB/s  

Installing collected packages: virtualenv 

Successfully installed virtualenv-15.1.0

安装完成后作一个软连接方便:

[root@docker myproject]# ln -sf /opt/py36/bin/virtualenv /usr/bin/virtualenv 
[root@docker Python-3.6.4]# mkdir /opt/myproject 
[root@docker Python-3.6.4]# cd /opt/myproject/

创建一个虚拟环境:

[root@docker myproject]# virtualenv py36env  
Using base prefix '/opt/py36'  
New python executable in /opt/myproject/py36env/bin/python3.6  
Also creating executable in /opt/myproject/py36env/bin/python  
Installing setuptools, pip, wheel...done.

激活虚拟环境:

[root@docker myproject]# source py36env/bin/activate 
(py36env) [root@docker myproject]#

安装flask和gunicorn,在上虚拟环境中安装:

(py36env) [root@docker myproject]# pip3 install gunicorn flask

创建一个简单的app程序:myapp.py

from flask import Flask 
app = Flask(__name__) 

@app.route("/") 
def hello(): 
    return "<h1 style='color:red'>Hello Python!</h1>" 

if __name__ == "__main__": 
    app.run(host='0.0.0.0')

运行程序:

(py36env) [root@docker myproject]# python3 myapp.py  

 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) 
10.0.10.1 - - [21/Jan/2018 03:57:04] "GET / HTTP/1.1" 200 - 
10.0.10.1 - - [21/Jan/2018 03:57:04] "GET /favicon.ico HTTP/1.1" 404 -

访问Url地址:http://10.0.10.29:5000 成功!

创建一个wsgi入口文件:wsgi.py

from myproject import app 

if __name__ == "__main__": 

    app.run()

启动程序:

(py36env) [root@docker myproject]# gunicorn --bind 0.0.0.0:8000 wsgi:app  

[2018-01-21 04:08:20 +0800] [2094] [INFO] Starting gunicorn 19.7.1  
[2018-01-21 04:08:20 +0800] [2094] [INFO] Listening at: http://0.0.0.0:8000 (2094)  
[2018-01-21 04:08:20 +0800] [2094] [INFO] Using worker: sync  
[2018-01-21 04:08:20 +0800] [2097] [INFO] Booting worker with pid: 2097  
[2018-01-21 04:08:52 +0800] [2094] [CRITICAL] WORKER TIMEOUT (pid:2097)  
[2018-01-21 04:08:52 +0800] [2097] [INFO] Worker exiting (pid: 2097)  
[2018-01-21 04:08:53 +0800] [2099] [INFO] Booting worker with pid: 2099

此时访问的时候不再是5000端口了,现在的端口是8000;

[root@docker yum.repos.d]# curl -I http://10.0.10.29:8000

为了方便添加一个开机启动gunicorn文件:/etc/systemd/system/myapp.service


[Unit] 
Description=Gunicorn instance to server myapp 
After=network.target 

[Service] 
User=nginx 
Group=nginx 
PrivateTmp=true 
WorkingDirectory=/opt/myproject 
Environment="PATH=/opt/myproject/py36env/bin" 
ExecStart=/opt/myproject/py36env/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 wsgi:app 

[Install] 
WantedBy=multi-user.target

启动程序:

systemctl start myapp

检查是否成功运行:

[root@docker yum.repos.d]# systemctl status myapp 

● myapp.service - Gunicorn instance to server myapp  
   Loaded: loaded (/etc/systemd/system/myapp.service; disabled; vendor preset: disabled)  
   Active: active (running) since Sun 2018-01-21 04:39:35 CST; 1min 6s ago  
 Main PID: 2624 (gunicorn)  
   Memory: 50.8M 

   CGroup: /system.slice/myapp.service  
           ├─2624 /opt/myproject/py36env/bin/python3.6 /opt/myproject/py36env/bin/gunicorn --workers 3 --bind 0.0.0.0:8000...  
           ├─2627 /opt/myproject/py36env/bin/python3.6 /opt/myproject/py36env/bin/gunicorn --workers 3 --bind 0.0.0.0:8000...  
           ├─2628 /opt/myproject/py36env/bin/python3.6 /opt/myproject/py36env/bin/gunicorn --workers 3 --bind 0.0.0.0:8000... 
           └─2637 /opt/myproject/py36env/bin/python3.6 /opt/myproject/py36env/bin/gunicorn --workers 3 --bind 0.0.0.0:8000... 


Jan 21 04:39:35 docker systemd[1]: Starting Gunicorn instance to server myapp...  
Jan 21 04:39:35 docker gunicorn[2624]: [2018-01-21 04:39:35 +0800] [2624] [INFO] Starting gunicorn 19.7.1  
Jan 21 04:39:35 docker gunicorn[2624]: [2018-01-21 04:39:35 +0800] [2624] [INFO] Listening at: http://0.0.0.0:8000 (2624)  
Jan 21 04:39:35 docker gunicorn[2624]: [2018-01-21 04:39:35 +0800] [2624] [INFO] Using worker: sync  
Jan 21 04:39:35 docker gunicorn[2624]: [2018-01-21 04:39:35 +0800] [2627] [INFO] Booting worker with pid: 2627  
Jan 21 04:39:35 docker gunicorn[2624]: [2018-01-21 04:39:35 +0800] [2628] [INFO] Booting worker with pid: 2628  
Jan 21 04:39:35 docker gunicorn[2624]: [2018-01-21 04:39:35 +0800] [2629] [INFO] Booting worker with pid: 2629  
Jan 21 04:40:11 docker gunicorn[2624]: [2018-01-21 04:40:11 +0800] [2624] [CRITICAL] WORKER TIMEOUT (pid:2629)  
Jan 21 04:40:11 docker gunicorn[2624]: [2018-01-21 04:40:11 +0800] [2629] [INFO] Worker exiting (pid: 2629)  
Jan 21 04:40:11 docker gunicorn[2624]: [2018-01-21 04:40:11 +0800] [2637] [INFO] Booting worker with pid: 2637

添加到开机启动:

[root@docker yum.repos.d]# systemctl enable myapp 

Created symlink from /etc/systemd/system/multi-user.target.wants/myapp.service to /etc/systemd/system/myapp.service.

现在通过Nginx来反向代理跳转到刚才的Flask项目上;

/etc/nginx/conf.d/app.conf

这里由于只是测试环境,所以直接使用IP地址,前提是把默认的那个nginx.conf里的server注释掉,不然会跟这个配置冲突。


server {  
    listen 80;  
    server_name default_server;  


    location / {  
        proxy_set_header Host $http_host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        proxy_set_header X-Forwarded-Proto $scheme;  
        proxy_pass http://127.0.0.1:8000;  
    }  
}

检查一下Nginx的配置,没有问题就可以启动Nginx服务了。此时直接访问IP地址,即可访问到我们的Flask项目了。

提醒:本文最后更新于 491 天前,文中所描述的信息可能已发生改变,请谨慎使用。