GitHook实现Django自动化部署

前言

项目中Django自动化部署的要求是:master分支,push了新的commit,需要自动拉去最新的代码,重启uwsgi,直接部署新版本上线。通过日志文件远程监控部署状态。

原来一直寄托与github的webhook来实现,但是这种第三方推送,自己服务器还需要单独开一个webhook服务单独跑来响应github的推送,操作很不方便!最不能忍的是 Github非常慢 git fetch一下都要等半天!

所以最后采用的方案是自己在阿里云上搭建git服务器,配上gitweb,效果基本和github一样,当然美观程度不及github,若追求美观,更好的方案是使用gitlab。相比于github好处有:

  1. git速度非常快,git clone/push/pull 基本是秒传,毕竟访问的是阿里云
  2. 私人仓库,对于团队项目没必要放到开源的github上
  3. 通过hooks非常方便实现自动化部署

自动化部署=git私服+githooks

Git服务器搭建

Google git服务器搭建,方案很多。主流是设置一个Git用户单独管理。其实对于小团队和个人用,直接使用root用户也是可以的。
下面创建hooktest的仓库。

1
2
3
4
cd /home/git
mkdir hooktest.git
cd hooktest.git
git init --bare

这样仓库创建好了,修改gitweb的配置文件指向git目录,在网页中就能看到了:
这里写图片描述

客户端clone仓库:

1
git clone root@阿里云ip:/home/git/hooktest.git

说明:
root :因为是root用户创建的
阿里云ip:也就是远端服务器的ip地址
/home/git/hooktest.git:项目仓库的地址
clone时会提示输入root用户的密码

如果clone成功则,说明git服务器搭建完成了。

Django项目配置

在生产环境中,Django项目是通过Nginx+uwsgi来部署的。具体参考:
Django在生产环境的部署
在本地仓库中创建Django项目,让项目能够运行起来。然后push到远端仓库中。
创建文件django_wsgi.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python
# coding: utf-8

import os
import sys

# 将系统的编码设置为UTF8
reload(sys)
sys.setdefaultencoding('utf8')

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hooktest.settings")

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

uwsgi_socket.xml

1
2
3
4
5
6
7
<uwsgi>
<socket>:8000</socket>
<chdir>/home/www/hooktest</chdir>
<module>django_wsgi</module>
<processes>1</processes>
<daemonize>/home/www/hooktest/static/log.txt</daemonize>
</uwsgi>

其中/home/www/hooktest/static/log.txtuwsgi日志文件,放到static目录下可以直接通过nginx查看日志
远端服务器Nginx配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;

# Make site accessible from http://localhost/
server_name zhujian.nghuyong.top;

location /static/ {
alias /home/www/hooktest/static/;
index index.html index.htm;
}


location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
}
}

这样重启nginx,clone代码到本地的www仓库,启动uwsgi项目就部署了。

Githook配置

githook,就是在有代码push的时候自动启动一个脚本。
要自动化部署,要操作的步骤包括:

  1. 拉去最新代码
  2. 关闭uwsgi
  3. 启动uwsgi
    在仓库hooks目录下创建post-receive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash -l
GIT_REPO=/home/git/hooktest.git
TMP_GIT_CLONE=/home/www/tmp/hooktest
PUBLIC_WWW=/home/www/hooktest
rm -rf ${TMP_GIT_CLONE} #删除临时仓库
git clone $GIT_REPO $TMP_GIT_CLONE #克隆到临时仓库
rm -rf ${PUBLIC_WWW} #删除www仓库
cp -rf ${TMP_GIT_CLONE} ${PUBLIC_WWW} #从临时目录拷贝到www目录
pid=`lsof -i:8000| awk 'NR==2{print $2}'` #获取项目uwsgi的pid,这里监听的是8000端口
echo "pid:$pid" 
kill -9 $pid #杀死进程,注意使用 -9
lsof -i:8000
nohup uwsgi -x ${PUBLIC_WWW}/uwsgi_socket.xml #重新启动uwsgi,注意nohup
lsof -i:8000
chmod 777 ${PUBLIC_WWW}/static/log.txt #增加log权限,可以通过web访问

注意的地方:
kill -9
nohup uwsgi...

这样push新的代码后,查看uwsgi的log,通过时间发现uwsgi已经重新启动,项目自动部署好了:
这里写图片描述
通过这个log可以随时监测项目的运行状况。