线上项目部署

Posted 孟郊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线上项目部署相关的知识,希望对你有一定的参考价值。

 

 centos7下部署Django(nginx+uwsgi+python3+django)

先连接服务器,使用命令行里面的ssh root@xxx  即可连接,这里的“xxx”就是服务器IP地址,会车后会提示输入密码,密码输入的时候是被隐藏的,输完即可连接服务器,然后进行命令行操作。

我们的python有现成的部署虚拟环境,这个东西,你下载好之后,不同的项目用到的是不一样的环境版本配置,为了更好的做隔离,需要用这个虚拟环境做区分。

这个虚拟环境是需要安装的,要安装到服务器中之后,才能基于它,使用下面的命令,然后配置你所需要的文件。我这里没有写安装过程,日后补上。

virtualenv

linux下virtualenv其它命令

列出虚拟环境列表

workon

也可以使用lsvirtualenv

新建虚拟环境

mkvirtualenv [虚拟环境名称]

启动/切换虚拟环境

workon [虚拟环境名称]

删除虚拟环境

rmvirtualenv [虚拟环境名称] 

 

我们项目部署需要用到uwsgi,它可以开启多进程,启动多个uwsgi实例,然后让nginx来做静态文件处理,以及负载均衡和反向代理.

{启动多个uwsgi通过nginx做集群,静态文件放到nginx,静态请求通过nginx直接相应,动态请求转发给uwsgi,如果在Windows上开发的话,配置了虚拟环境,否则安装一些python包和依赖会有问题}

 

接上面的虚拟环境virtualenv


yum install lrzsz
nginx里面可以做反向代理,负载均衡(LVS更大平台做做负载均衡,haproxy也是),处理静态文件,
uwsgi处理动态请求
linux里面命令后加上&符号都是在后台运行
tornado里面部署只需要用nginx就可以,
在安装python前先安装各类基础模块
yum install gcc-c++
yum install wget openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel
yum install libxml*
yum -y install zlib*
yum remove lrzsz -y
yum install lrzsz -y
关闭防火墙
systemctl stop firewalld
———————————————————————————————-
编译安装python3
mkdir /application/
cd /application/
wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz
tar xf Python-3.6.3.tgz -C /usr/local/src/
cd /usr/local/src/Python-3.6.3/
./configure –prefix=/usr/local/python3
make && make install

 

连上服务器之后先进入为项目新建的虚拟环境中,然后在git上把项目拉下来,这里用git是比较方便的,用其他方法也行,比如硬拖拽也可以,下一些依赖包即可。

然后在服务器的虚拟环境中生成requirements.txt文件,建议使用

pipreqs <path>
path是项目路径,在当前路径就用
pipreqs ./

 

一般就能直接生成,我自己遇到过报错,提示ascii编码有问题,后来发现是iTerm编辑器不能显示中文,后来改了iTerm的编码就可以运行了

然后下载项目所需要的包和依赖,在当前路径下载,或者把requirements文件的路径贴到-r后面也一样

pip install -r requirements.txt

 

然后把数据库连接做好,要连上服务器的数据库,ip,端口,库名,数据库用户名,数据库用户密码。

还要做数据库迁移,

python manage.py makemigrations & python manage.py migrate
然后启动文件
python manage.py runserver 0.0.0.0:8000

 

此时应该可以访问到你的项目地址了

 

如果有报错,就需要你去排查项目本身的问题了。

 

再来配置uwsgi

pip install uwsgi

 

然后创建一个uwsgi.ini 文件,可以在任何地方,前提是你必须要记住它的绝对路径,它是启动uwsgi服务的启动文件,必须要能清晰地找到它的绝对路径

我是创建在跟项目同级的目录下的

项目目录地址:/data/oldboy/

目录结构如下:

-oldboy

  -app01

  -app02

  -oldboy

    -setting

    -url

    -wsgi.py

  -static

  -templete

 

创建uwsgi文件,

cd /data/

mkdir script

cd script/

touch uwsgi.ini

 

然后在里面加上参数:

先上一个简单版本:

http = 0.0.0.0:9005  # ip:端口
chdir = /data/oldboy/  # 项目根目录 项目名称(oldboy)
wsgi-file = oldboy/wsgi.py  # 项目名称(oldboy)/wsgi.py  --->这里的wsgi.py是Django项目的启动文件(固定的),凡是Django项目,找到setting文件,它同级的有一个wsgi文件,就是它
# 如果是flask项目,就把flask项目的启动文件放这里,因为flask的目录是自定义的,找到Flask类实例化出来的变量名(例“app”),有app.run()这一行命令的文件,它就是启动文件,放到这个参数即可 # flask启动文件也要带上路径
processes
= 4 # uwsgi的启动进程数量

 

还需要补充的一点就是module参数,它跟wsgi-file是可以互换的,两者取其一

module=oldboy.wsgi # 跟上面的wsgi-file写法不同,但是格式是一样的,Django项目专用写法。

flask写法:
app = hello # 这里是写有“app.run()” 的那个启动文件的文件名
module = %(app) # 然后这里跟上一行同时存在。
这个配置还没有试过,先留着。也许有坑。

 

还有一种配置文件参数要更多一些:

[uwsgi]
# 项目目录
chdir=/data/oldboy# 启动uwsgi的用户名和用户组
uid=root
gid=root
# 指定项目的application
module=pro.wsgi
# 指定sock的文件路径,这是跟nginx配合使用的,如果先配置好uwsgi想试一下效果,就把它先注释掉。
socket=/data/script/uwsgi.sock  
# 启用主进程
master=true
# 进程个数
workers=5
pidfile=/data/script/uwsgi.pid
# 自动移除unix Socket和pid文件当服务停止的时候
vacuum=true
# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 设置自中断时间
harakiri=30
# 设置缓冲
post-buffering=4096
# 设置日志目录  (这里遇到坑了,如果还没有配nginx,建议先注释掉,我试过如果不注释掉无法启动uwsgi,按理说逻辑不应该是这样的,解释不通,但是现象如此,大家可以多试试。nginx配好打开注释即可)
daemonize=/data/script/uwsgi.log  
########################################

 

 

我们这里有提示过,daemonize和socket这两个参数先注释掉,然后启动uwsgi服务。此时可以关掉上面python manange.py runserver的服务了。

进入到上面的uwsgi.ini文件的目录下面,执行启动服务命令

uwsgi --ini  uwsgi.ini

 

停止服务命令,同上也要在该文件的路径下才可以执行如下命令

uwsgi –stop uwsgi.pid

查看uwsgi日志  # 前提是有日志配置能生成日志
tail -f /data/script/uwsgi.log

 


就能看到如下提示:

*** Starting uWSGI 2.0.17.1 (64bit) on [Mon Mar 25 19:18:37 2019] ***

然后我们在浏览器url里面输入指定的IP端口以及项目中的地址和参数,就可以访问服务了,跟python manage.py runserver一样的效果,页面可以正常访问。

同时我们在项目目录中会看到生成了一个新的文件夹“static_all”,里面是我们的项目里面的静态文件。注意:不能用Django项目自带的static目录,要另外建立一个,不要同名。

到此,uwsgi配置就完成了,主要就是把Django项目静态文件路径加一行配置,然后下载uwsgi模块,创建一个uwsgi.ini文件,然后把必须的参数配好放进去,就能启动uwsgi服务了。

 

接下来就是配置nginx了。后续会补充docker的配置,以及flask项目的配置。

 

先查看有没有装nginx  
nginx -v
如下显示:说明有
nginx version: nginx/1.15.10

没有的话有简易安装方法,用yum
yum install -y nginx

 

 


————————————————————————————————
- 编译安装nginx cd /application/ wget http://nginx.org/download/nginx-1.10.3.tar.gz yum install pcre-devel openssl-devel -y tar xf nginx-1.10.3.tar.gz cd nginx-1.10.3 useradd -s /sbin/nologin -M www ./configure make &&make install ————————————————————————————————-
编译安装的话,启动命令跟非编译安装是不一样的,小心有坑。

 

 先找到配置文件地址

cd /etc/nginx

ls
找到nginx.conf,然后进行编辑。
如果不想用默认的进行编辑,也可以自己新建立一个文件,放到任何位置都行,重新配置也可以的(不过前提是要把默认的这个文件备份后删除原件,备份的时候另外起个文件名)。
这里是用的原文件编辑的
vim nginx
.conf

 

具体参数如下:user root; # 这里用户要写成root,如果写成nobody,有坑,我踩过,改成root就能启动。worker_processes 4; # 进程数


  user root;  # 这里的user参数必须要设成root,否则会无法启动nginx服务,
  worker_processes 4;

events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    log_format  main  \'$remote_addr - $remote_user [$time_local] "$request" \'
                      \'$status $body_bytes_sent "$http_referer" \'
                      \'"$http_user_agent" "$http_x_forwarded_for"\';
    server {
                    listen 80;
                    server_name www.phno2.xyz;  # 这里是你项目的url地址,或者写成  localhost  也行。
                    access_log  /etc/nginx/logs/django.log;  # 这是自己设定的nginx正常输出日志的日志地址
                    error_log  /etc/nginx/logs/errordjango.log;  # 也是自己设定的,nginx错误日志地址
                    charset  utf-8;
                    gzip on;
                    error_page  404           /404.html;
                    error_page   500 502 503 504  /50x.html;
                    # 指定项目路径uwsgi
                    location / {
                        include /etc/nginx/uwsgi_params; # 这里的uwsgi_params是系统自带的,路径都是一样的,把路径写完整即可。
                        uwsgi_connect_timeout 30;
                        uwsgi_pass unix:/data/script/uwsgi.sock; #*****这里是五颗星,必须要改动的,而且是起关键作用的参数。unix: 是固定语法,
# 它后面是uwsgi配置的时候,socket参数后面的值,一定要跟uwsgi配置文件的socket参数保持一致,要一模一样。我这里都是用的sock文件路径,可以直接写IP:port,要写IP:port的话,就uwsgi和nginx
# 在相应的位置都写上IP:port,而且必须是一样的值。
}
# 指定静态文件路径 location /static/{ # 这里的static是我们自己后来加上的,用于处理静态文件,这都是固定语法, root /data/oldboy/; # root是必须要写的,之前试过用alias替代root,会报错,找不到静态文件。还有一点是这里只需要写到项目的根目录即可,项目下一级的目录就不必写了,
# 因为在Django配置里面还要加上静态文件的路由分发,如果多写一层会报错,浏览器会找不到静态文件的。亲测有效,都是自己踩过的坑。 } } }

 

 

Django项目的setting文件需要在文件末尾加一条配置项:

STATIC_ROOT = os.path.join(BASE_DIR, "allstatic")

 这是把Django所有的静态文件都收集到了这个文件里面---allstatic,让nginx集中处理用,还要执行下面的命令

cd /data/oldboy/oldboy/ # 找到项目目录下有manage.py文件的那个位置,执行这一条。

python3 manage.py collectstatic

 

然后查看项目,会自动生成一个名为“allstatic”的文件夹。


自此,nginx配置完成。

可以启动项目了。
上面已经启动了uwsgi,这里把uwsgi重新启动,之后,启动nginx
nginx

 

这就是启动命令,我是用yum安装的,用它就能启动(这个命令敲完,屏幕没有任何提示信息,即成功启动,可以去访问项目了,若是有提示信息就是报错了,查日志排错)

如果是编译安装就不是这个命令了,小心有坑。

 

查看nginx的进程

ps -ef |grep nginx

root 16293 14550 0 18:57 pts/1 00:00:00 grep --color=auto nginx  # 这一条不是进程,是你输入上面的命令,系统提示给你的反馈,忽律即可。
root 32466 1 0 13:27 ? 00:00:00 nginx: master process nginx  # master process是主进程,杀进程杀它即可停掉所有的nginx服务
root 32467 32466 0 13:27 ? 00:00:00 nginx: worker process
root 32468 32466 0 13:27 ? 00:00:00 nginx: worker process
root 32469 32466 0 13:27 ? 00:00:00 nginx: worker process
root 32470 32466 0 13:27 ? 00:00:00 nginx: worker process

 

 

停止nginx服务就杀进程即可(uwsgi服务也能杀进程停止服务)

kill 32466

 

在服务器(centos)中nginx默认日志路径

/var/log/nginx/

 

我们用yum装的许多插件,配置文件中默认日志路径就是在

/var/log/

还有一个类似启动文件的文件夹

/var/run/

这个var路径要记住,会很常用,日志在开发过程中,起到很关键的作用。

 

经常在部署时会遇到端口占用问题,这里查询端口占用情况,命令如下

netstat -tunlp |grep 27017

 

总结,核心点就是创建uwsgi配置文件,把核心参数配置好,module/wsgi-file(项目启动文件),chdir(项目根目录),然后设置nginx的配置文件核心参数,uwsgi_pass(跟uwsgi的socket相应的参数值,还有root,以及固定的unix:语法),location /static/ (静态文件路径),user(参数值必须要是root),项目的setting文件再加一个静态文件路径分发,再无其他,项目本身能运行,就已经完成了Django+uwsgi+nginx的所有配置。

 

PS:如果nginx还有media文件需要配置,参考static,逻辑一样。


gunicorn 部署

配置文件gunicorn.conf.py
import os
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
bind = "0.0.0.0:80"
workers = 2
accesslog = os.path.join(base, "check_list_app/flask_logs/access_guni.log")
errorlog = os.path.join(base, "check_list_app/flask_logs/error_guni.log")
pid = os.path.join(base, "check_list_app/flask_logs/pid_guni.log")
daemon = True

如果用配置文件启动服务,命令如下

gunicorn -c/--config  gunicorn.conf.py  manage:app

 

或者写成shell脚本

gunicorn.sh
#
!/bin/bash gunicorn --bind 0.0.0.0:8080 --workers 2
--access-logfile ./flask_logs/gunicorn_access.log
--error-logfile ./flask_logs/gunicorn_error.log
--pid ./flask_logs/gunicorn_pid.log manage:app &

写成脚本,需要加上权限设置,

chmod u+x gunicorn.sh

直接执行脚本即可

 

最简单的命令行启动服务

gunicorn -b 0.0.0.0:80 manage:app

这里的manage是文件manage.py的名字,这个文件是启动文件,如果你的项目启动文件是run.py ,那么这里就是run:app;

这里的app是我们的项目实例化出来的对象,这里我用的是flask项目示例,所以Flask实例化对象我取名为app,如你的项目是abc = Flask(__name__),那么就替换app成为abc。

个人感觉用gunicorn比uwsgi要方便些。

 

wusir部署博客地址

孙铭浩博客地址

 

flask部署uwsgi配置文件

[uwsgi]
http=0.0.0.0:9000
chdir=/data/cad_project_service/
touch-reload=/data/cad_project_service/
callable=app
wsgi-file=/data/cad_project_service/views.py
# 配置的时候这个参数可以重启uwsgi服务,用单纯的kill是无法杀死进程的 daemonize
= /data/cad_project_service/logs/uwsgi.log
# 这个是pidfile的配置参数,启动uwsgi之后,会把主进程写入到这个文件中,文件需要自己touch一下,uwsgi才能写入进程id。这个文件是作为kill进程的窗口
# 写好这个,以后要kill进程的时候只需要在这个pidfile的路径下执行一条命令即可
pidfile = /data/script/uwsgi.pid

2020-06-12更新的最新版。亲测可用,在服务器测试过。

# stop 后面是pidfile的路径,这样就能直接杀死进程了
uwsgi --stop /data/script/uwsgi.pid

 

在uwsgi的配置文件中,如果没有配置pidfile,但是配置了daemonize参数,要杀死进程,就需要如下命令

ps aux|grep uwsgi
#kill pid会发送SIGTERM,只会导致重启,而不是结束掉。需要找到你的uwsgi文件路径,写入到INT后面才可以。如果不知道的话可以用命令查一下
# 查看uwsgi的文件路径
which uwsgi
# 如下是显示结果
/admin/.virtualenvs/py35_flask/bin/uwsgi
# 这样在killall就能杀死uwsgi进程了。需要再启动的话就还是用uwsgi --ini uwsgi.ini 命令即可。uwsgi.ini文件记得带上路径,或者就在该文件路径下执行此命令 killall
-s INT /admin/.virtualenvs/py35_flask/bin/uwsgi

 

以上是关于线上项目部署的主要内容,如果未能解决你的问题,请参考以下文章

线上项目部署

项目部署github实现线上阅览

Nginx线上部署多个Vue项目(路径区分)

Node.js项目的线上服务器部署与发布

Nodejs 项目的线上服务器部署与发布

webhook 自动部署代码