云服务器上的flask项目部署(anaconda、python、flask等相关安装)
在探索未知的路上走了很多弯路,这里记载了我在阿里云上部署项目切实可行的步骤,当然问题因人而异,没有四海皆适用的准则。
因为ubuntu系统在安装之后会自带两个python环境(python2.7和python3.5),所以你可以直接请自行跳过anaconda、python安装步骤。
1、安装anconda
Anconda真是好东西,可以解决我们很多问题。请自行前往官网下载Linux版本:https://www.anaconda.com/distribution/#download-section
当然在官网下载特别慢,这里建议使用国内镜像资源:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
安装好之后通过xftp将安装包传输到云服务器文件夹中。
安装Anaconda建议不要用root用户,即安装在自己的普通用户home目录下即可:
bash *.sh
一路进行确认yes即可,安装完成后后会出现Anaconda3文件夹在home目录下:
~/Anaconda3/ (以anaconda3为例)
进入安装包所在的文件夹中(下面是详细的命令):
#进入文件所在文件中
cd /home
#使用命令进行安装
bash Anaconda3-5.2.0-Linux-x86_64.sh -u
#安装pip文件
sudo apt update
sudo apt install python-pip
#安装conda
pip install conda
#切换环境
source ~/.bashrc
注意安装过程中最后会问是否配置环境变量,记得选择yes,如果错过了,则需要手动配置环境变量
如果 提示conda: command not found,可以尝试
export PATH=~/anaconda3/bin:$PATH
切换好环境之后会发现出现 base标志。
在使用conda命令前,要先进行安装conda
sudo apt-get update
apt install python-pip
由于Anconda自带镜像源下载十分缓慢,这里我建议切换镜像源为清华大学的开源版本。
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
而后在命令行中输入:
python
如果安装成功,便会出现python的版本信息,否则则为安装失败。
至此,anaconda软件安装完成。
注意:当然你也可以这样下载:(在线使用清华大学的镜像资源,很快)
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.3.1-Linux-x86_64.sh
2、安装python虚拟环境
由于在实际生产、开发需求中,我们需要进行不同项目的开发部署,因此我们可以考虑进行设置虚拟环境,将每个项目环境进行隔离,这样就方便我们的需求。而进行虚拟环境的设置有很多种方法,这里我们就使用最简单的anaconda自带的功能进行处理。
- 查看虚拟环境
conda env list
- 创建新的虚拟环境
conda create -n env_name python=version package_names
//-n 指定虚拟环境名,与--name等效。
//python=version是为虚拟环境指定Python版本
//package_names是要为新的虚拟环境创建时就安装的包,可省略这一参数
- 激活虚拟环境
source activate env_name
- 切换到虚拟环境
conda activate env_name
//要进行激活的虚拟环境名
- 退出当前的虚拟环境
conda deactivate
- 删除虚拟环境
conda remove -n env_name --all
//env_name 虚拟环境名称
至此虚拟环境和python环境安装完毕。
3、搭建flask环境
一行代码解决安装:
pip3 install flask
#或者
conda install flask
新建一个目录,webtest1,在该目录下新建一个webtest.py
直接vim编辑:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#webtest.py
from flask import Flask,request
app = Flask(__name__)
@app.route('/')
def home():
return "home"
if __name__ == '__main__':
app.debug=False
app.run(host='0.0.0.0')
此时使用python进行运行:
在浏览器输入地址
截止这一步,其实我们简单完成了webapi的部署。下面的步骤都是辅助性的,目的在于提高性能,让这个web应用不容易崩。
4、安装运行gunicorn
gunicorn是一个WSGI服务器,类似于JAVA中的tomcat。上一步中我们使用的是flask 自带的服务器,完成了 web 服务的启动。生产环境下,flask 自带的服务器,无法满足性能要求。我们这里采用 gunicorn 做 wsgi容器,用来部署 python。
(1)在虚拟环境中安装gunicorn
pip install gunicorn
(2)用gunicorn运行web应用
gunicorn -b 0.0.0.0:5000 webtest:app
webtest对应的是py文件名,app对应的是文件中Flask的实现名,这里默认开启的是8000端口。
运行结果:
5、安装配置nginx
这里,具体见我写的另一篇博文:https://blog.youkuaiyun.com/qq_36789311/article/details/104799589
sudo apt-get install nginx
server {
listen 80;
server_name 127.0.0.1;
location / {
try_files $uri @gunicorn_proxy;
}
location @gunicorn_proxy {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:8000;
proxy_connect_timeout 500s;
proxy_read_timeout 500s;
proxy_send_timeout 500s;
}
}
service nginx start
6、supervisor进程守护
Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。
除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动
(1)安装supervisor(不在虚拟环境里)
pip install supervisor 或者使用 sudo apt-get install supervisor
这里个人建议使用后面的命令行。
liu@codepanda:~$ sudo apt-get install supervisor
(2)配置文件 supervisor.conf
如果是使用apt-get安装的,那么 这个supervisord.conf文件会在 /etc/supervisor/文件夹下自动生成
; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf
配置文件最后一行,设置的是要运行的进程的配置文件路径,可见只要后缀名是conf即可被识别,于是新建文件/etc/supervisor/conf.d/webtest.conf
[program:webtest]
directory = /home/liu/webtest/ ; 程序的启动目录
command =/home/liu/anaconda3/envs/tutle-tf/bin/gunicorn -k gevent -t 300 run:app ; 启动命令,可以看出与手动在命令行启动的命令是一样的
autostart = true ; 在 supervisord 启动的时候也自动启动
startsecs = 5 ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true ; 程序异常退出后自动重启
startretries = 3 ; 启动失败自动重试次数,默认是 3
user = liu ; 用哪个用户启动
redirect_stderr = true ; 把 stderr 重定向到 stdout,默认 false
stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 20 ; stdout 日志文件备份数
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /home/liu/webtest/webtest.log
; 可以通过 environment 来添加需要的环境变量,一种常见的用法是修改 PYTHONPATH
; environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere
根据实际情况,自行进行修改路径和配置。
(3)设置并启动supervisord(服务端)
首先,supervisord运行是需要有配置文件的,启动supervisord可以直接命令行运行
此处可能报错如问题集锦中的【2】、【3】、【4】。
supervisord
这时,supervisor会默认依次在这几个路径下寻找配置文件
$CWD/supervisord.conf,
$CWD/etc/supervisord.conf,
/etc/supervisord.conf
如果这几个路径下没有该配置文件,则启动失败。
所以如果配置文件在其他位置例如/your_file_path/supervisord.conf ,则需要用 -c 设置
supervisord -c /your_file_path/supervisord.conf
(4)启动supervisorctl(客户端)
sudo supervisorctl -c /your_file_path/supervisord.conf
这里客户端和服务端要使用同一个supervisord.conf文件,要确保两者使用的是同一个!要么都默认位置,要么都指定同一位置。
这样就可以进入supervisor客户端:
这里的web应用是对应的/etc/supervisor/conf.d/webapi.conf文件里的配置的,我的配置文件有两个即
webapp 和 webtest
这样,web接口进程就被supervisor守护了,关掉终端也无所谓了。
如果要关闭应用进程,则进入supervisorctl
里面有stop;start;restart等命令,后跟web应用名即可
supervisor
常用命令:
# 读取有更新(增加)的配置文件,不会启动新添加的程序
$ supervisorctl reread
# 重启配置文件修改过的程序
$ supervisorctl update
# 查看程序状态
$ supervisorctl status
# 启动程序 App_name
$ supervisorctl start App_name
# 关闭程序 App_name
$ supervisorctl stop App_name
# 重启程序 App_name
$ supervisorctl restart App_name
以上命令也可以在supervisorctl Shell中执行:
$ supervisorctl
supervisor> reread
supervisor> update
supervisor> status
supervisor> start App_name
supervisor> stop App_name
supervisor> restart App_name
================================================
这里提供另一种思路,使用pm2进行管理python进程
pm2 start main.py -x --interpreter python
7、部署过程中可能出现的错误:
【1】错误提示: unknown error making dispatchers for ‘etcd’: EACCES
错误原因: 配置项中的stdout_logfile目录权限不对,logfile是 root:root,而我的用户是liu, 改为liu/liu就可以了
sudo chown -R liu:liu 文件名/文件夹名
【2】日志权限错误:IOError: [Errno 13] Permission denied: '/var/log/supervisor/supervisord.log'
错误原因:/var/log/supervisor/supervisord.log没有写权限,赋予权限即可:
sudo chmod -R 777 /var/log/supervisor/supervisord.log
【3】开启HTTP Server错误
Error: Cannot open an HTTP server: socket.error reported errno.EACCES (13)
配置文件中 /var/run 文件夹,没有授予启动 supervisord 的相应用户的写权限。/var/run 文件夹实际上是链接到 /run,因此我们修改 /run 的权限。
sudo chmod 777 /run
一般情况下,我们可以用 root 用户启动 supervisord 进程,然后在其所管理的进程中,再具体指定需要以那个用户启动这些进程。
详细解决参考:https://www.cnblogs.com/xiwang/p/6228909.html
【4】Starting supervisor: Unlinking stale socket /var/run/supervisor.sock
错误原因:supervisor可以通过python2 的pip安装, 可以通过apt安装, 不支持python3
错误解决:
find / -name supervisor.sock
unlink /***/supervisor.sock
详细解决参考:https://www.jianshu.com/p/3658c963d28b
【5】警告:Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
解决参考:https://blog.youkuaiyun.com/feng98ren/article/details/84874326
最后,特别感谢https://www.jianshu.com/p/484bd73f1e80博文进行学习。
参考博客:
【1】https://www.jianshu.com/p/484bd73f1e80
【2】https://blog.youkuaiyun.com/weixin_42042680/article/details/97183618
【3】https://www.cnblogs.com/xiwang/p/6228909.html
【4】https://blog.youkuaiyun.com/daduryi/article/details/81299892
【5】https://www.jianshu.com/p/3658c963d28b
【6】【非常重要】运行supervisorctl错误提示【FATAL或BACKOFF 】Exited too quickly (process log may have details)问题总结https://blog.youkuaiyun.com/weixin_43343144/article/details/97688485