看完这篇Django博客部署就足够了


每次写好一个博客之类的项目,都想把它部署在我的云服务器上,这样就可以方便访问,但每次部署都容易掉了莫名其妙的坑里面,总是要谷歌各种问题才能彻底解决。所以这篇文章当做以后部署的笔记使用,免得每次都要查很多资料。

一、部署所需条件

首先你要部署项目的话,你得先有个服务器,一般来说只要你电脑装了Liunx系统都行,只要你不关机。但最好还是花钱买个云服务器使用,现在国内的阿里云、腾讯云都不错,而且是学生的话还有学生优惠。先贴出部署前提条件

  • Liunx环境 (我使用的是Ubuntu系统)
  • Python2.7
  • Django1.8 (注版本不一样的可能需要改一些配置)
  • Virtualenv (Virtualenv是一个Python虚拟环境管理的工具)
  • Supervisor (Supervisor是一个客户端/服务器系统,允许其用户在类UNIX操作系统上控制多个进程)
  • Nginx (Nginx 是一个高性能的 Web 和反向代理服务器)

我使用的是美团云服务器Ubuntu16.04来实现整个部署过程,如果对以上列举的工具不熟悉的话,请自己去谷歌文档看看,这里就简单概括下部署的流程,首先把以上环境搭建好,并根据需要配置好所需的环境。其次就可以Supervisor来管理进程,Nginx是用来反向代理的,把对域名的访问反向到Django的进程中,下面会具体地说。


二、 安装Python及Django依赖包

安装Python环境
  • 我使用的Ubuntu系统已经预装了Python2.7和Python3.4。其它的Liunx系统如CentOS, Fedora, Red Hat也预装了Python2.7。如果没有的话,请谷歌找一下对应系统的安装教程,一般都是通过命令行就可以安装了。
安装Django框架
  • 一般安装Django使用的是Python的包管理工具pip。如果没有pip的话,ubuntu系统可以通过:

      $ sudo apt-get install python-pip
    

然后就可以愉快的使用pip安装python的各种扩展包了,安装Django可以使用

    pip install Django==1.8

就这么简单搭建后安装了Django,如果没有指定版本号,默认就是最新的版本。不过这里我们先不需要使用这条语句安装Django,因为这里存在一个问题就是,pip安装的Django是全局有效的,如果你的服务器有其它项目依赖于Django的其它版本,这样安装的话就会导致其它项目直接崩盘了, 这就需要一个虚拟环境让你的Web应用的Python环境从系统的python环境直接隔开来。

安装virtualenv
  • virtualenv是一个Python虚拟环境管理的工具,作用是把你项目的python环境和系统全局的python环境隔开来,这样你就可以在不同的项目中安装不同版本的第三方库。在Ubuntu系统下安装virtualenv,可以使用pip安装或者apt-get安装:

      $ pip install virtualenv
      $ sudo apt-get install python-virtualenv
    

三、virtualenv使用

在你项目根目录下执行下面语句:

$ cd /home/guoweikuang/django_web   # cd到你项目目录下
$ virtualenv virtualenv   #创建虚拟环境,会在当前的目录中创建一个文件夹,包含了Python可执行文件, 以及 pip 库的一份拷贝
$ source virtualenv/bin/activate  # 激活虚拟环境

然后你会看到下面的命令行前面有虚拟环境的名字:
(virtualenv) ➜ guoweikuang
如果要退出虚拟环境,你可以使用:

$ deactivate

在虚拟环境下pip安装的和系统全局的python库是隔开的,如果你不想一条一条pip安装第三方库的话,你可以使用

$ pip install -r requirements.txt

其中requirements.txt里面内容是你项目所需的第三方库的名字和版本号,你可以使用

$ pip freeze > requirements.txt

来生成requirements.txt文件,前提是你之前要是没有requirements.txt文件的话,你需要一条一条的pip,但是有这个文件后你迁移到其它地方安装第三方库也只需要 pip install -r requirements.txt 就可以了。


四、Supervisor安装配置

Superviosr是一个进程管理工具,可以保证你的程序在服务器开机时自动启动以及程序意外终止时重新启动。当你的项目有多个并且需要同时启动或关闭,使用Supervisor一行命令都可以同时重启,而不是一个一个命令地重启。

supervisor 主要由两部分组成:

supervisord(server 部分):主要负责管理子进程,响应客户端命令以及日志的输出等;
supervisorctl(client 部分):命令行客户端,用户可以通过它与不同的 supervisord 进程联系,获取子进程的状态等。

首先,可以通过pip安装supervisor或者apt-get安装:

$ sudo pip install supervisor
$ sudo apt-get install supervisor 

安装完 supervisor 之后,可以运行echo_supervisord_conf 命令输出默认的配置项,也可以重定向到一个配置文件里:

echo_supervisord_conf > /etc/supervisord.conf

Supervisor提供了很多配置给我们使用。首先来看 supervisord 的配置文件:

1、supervisord(这是 server 端,对应的有 client 端:supervisorctl)
2、应用程序(即我们要管理的程序)。

首先来看 supervisord 的配置文件。去除里面大部分注释和“不相关”的部分,我们可以先看这些配置:

[unix_http_server]
file=/tmp/supervisor.sock   ; UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ; socket 文件的 mode,默认是 0700
;chown=nobody:nogroup       ; socket 文件的 owner,格式: uid:gid
;[inet_http_server]         ; HTTP 服务器,提供 web 管理界面
;port=127.0.0.1:9001        ; Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
;username=user              ; 登录管理后台的用户名
;password=123               ; 登录管理后台的密码
[supervisord]
logfile=/tmp/supervisord.log ; 日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ; 日志文件大小,超出会 rotate,默认 50MB
logfile_backups=10           ; 日志文件保留备份数量默认 10
loglevel=info                ; 日志级别,默认 info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ; pid 文件
nodaemon=false               ; 是否在前台启动,默认是 false,即以 daemon 的方式启动
minfds=1024                  ; 可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ; 可以打开的进程数的最小值,默认 200
; 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:///tmp/supervisor.sock ; 通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致
;serverurl=http://127.0.0.1:9001 ; 通过 HTTP 的方式连接 supervisord
; 包含其他的配置文件
[include]
files = relative/directory/*.ini    ; 可以是 *.conf 或 *.ini

里面需要注意的是配置

[include]
files= /etc/supervisor/conf.d/*.conf   ; 你项目的配置文件所在地方

然后启动supervisord, 通过 -c选项指定配置文件路径:

supervisord -c /etc/supervisord.conf

查看 supervisord 是否在运行:

ps aux | grep supervisord

我们可以看到 supervisord 已经被启动了, 然后进入 supervisorctl 的 shell 界面:

$ supervisorctl
django_web                       RUNNING   pid 58261, uptime 3:21:25
supervisor>status

可以看到如果有进程运行的后会显示状态信息之类,进程ID,启动时间等。
接下来就添加一个需要管理的进程:
按照官方文档的定义,一个 [program:x] 实际上是表示一组相同特征或同类的进程组,也就是说一个 [program:x] 可以启动多个进程。这组进程的成员是通过 numprocs 和 process_name 这两个参数来确定的.
下面以我部署的django_web进程配置为例:

[program:django_web]
directory = /home/guoweikuang/django_web   ;程序放置目录
#command = gunicorn django_blog.wsgi:application -b 127.0.0.1:8090
command = runinenv /home/guoweikuang/virtualenv python manage.py runserver 127.0.0.1:8080
# command = sudo /home/guoweikuang/virtualenv/bin/gunicorn django_blog.wsgi:application -b 127.0.0.1:8080 ; 启动命令,和在命令行模式下都是一样的
#autostart = true   ; 在supervisord启动时自动启动
user=www-data       ; 使用哪个用户启动进程
startsecs = 5       ; 启动5秒后没有异常就相当于正常启动
startretries = 3    ; 启动失败后自动重试次数,默认为3
stopsignal = KILL   ; 下面有解释
stopasgroup = true
redirect_stderr = true   ; 把stderr重定向到stdout, 默认为false
stdout_logfile = /var/log/supervisor/django_web.log   ; 日志文件,方便查看
stderr_logfile = /var/log/supervisor/django_web_error.log

Supervisorctl命令介绍

# 停止某一个进程,program_name 为 [program:x] 里的 x
supervisorctl stop program_name
# 启动某个进程
supervisorctl start program_name
# 重启某个进程
supervisorctl restart program_name
# 结束所有属于名为 groupworker 这个分组的进程 (start,restart 同理)
supervisorctl stop groupworker:
# 结束 groupworker:name1 这个进程 (start,restart 同理)
supervisorctl stop groupworker:name1
# 停止全部进程,注:start、restart、stop 都不会载入最新的配置文件
supervisorctl stop all
# 载入最新的配置文件,停止原有进程并按新的配置启动、管理所有进程
supervisorctl reload
# 根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启
supervisorctl update

五、Supervisor容易出现的问题

一、管理的进程会产生新的进程时, 会遇到执行完stop命令后子进程依然在: 这是我使用supervisor启动了一个django, 可以看到有俩进程:

www-data 102180  2.2  3.1  80760 31312 ?        S    08:38   0:00 python manage.py runserver 127.0.0.1:8080
www-data 102185  3.4  3.6 156932 36140 ?        Sl   08:38   0:00 /home/guoweikuang/virtualenv/bin/python manage.py runserver 127.0.0.1:8080

当你stop进程时,使用ps aux | less 查看进程时你会看到还有下面这个进程没有停止:

www-data 102185  1.1  3.6 156932 36140 ?        Sl   08:38   0:02 /home/guoweikuang/virtualenv/bin/python manage.py runserver 127.0.0.1:8080

为了关闭子进程, 这里需要介绍两个配置项 stopasgroup 和 killasgroup:

; 默认为 false,如果设置为 true,当进程收到 stop 信号时,会自动将该信号发给该进程的子进程。如果这个配置项为 true,那么也隐含 killasgroup 为 true。例如在 Debug 模式使用 Flask 时,Flask 不会将接收到的 stop 信号也传递给它的子进程,因此就需要设置这个配置项。
stopasgroup=false            ; send stop signal to the UNIX process 

; 默认为 false,如果设置为 true,当进程收到 kill 信号时,会自动将该信号发给该进程的子进程。如果这个程序使用了 python 的 multiprocessing 时,就能自动停止它的子线程。
killasgroup=false            ; SIGKILL the UNIX process group (def false)

当增加 stopasgroup=true 配置后, 父进程关闭子进程也就关掉了.

二、需要注意的是权限问题,如果出现:

error: <class 'socket.error'>, [Errno 13] Permission denied: file: /usr/local/lib/python2.7/socket.py line: 228在[Permession denied error when use supervisorctl #173][1]

解决方法:就是在supervisod.conf文件中修改权限为0766:

[unix_http_server]
file=/tmp/supervisor.sock   ; (the path to the socket file)
chmod=0766                 ; socket file mode (default 0700)

最后别忘了重启supervisor使其生效:

sudo service supervisor restart

未完待续。。。。。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容

  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    aimaile阅读 26,294评论 6 428
  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    小迈克阅读 2,861评论 1 3
  • 前言 《Django开发简单Blog系统》系列中,我们已经完成了一个迷你Web项目。那么,怎么把这个项目发布到线上...
    VoidKing阅读 2,244评论 0 4
  • Python常用库大全,看看有没有你需要的。 环境管理 管理 Python 版本和环境的工具 p – 非常简单的交...
    XDgbh阅读 15,744评论 4 147
  • 前几年隔壁条马路在修高架,对于大家来说也许是件好事,不但可以让我们以后的出行更加便捷,也一定程度上缓解下面的地面交...
    就看看wechat阅读 204评论 0 0