β

用git布署网站的方法

炒饭的小站 97 阅读

大家都知道github提供了搭建静态页面网站的方式,也就是github.io。其使用方式是建一个指定名称的版本库,以版本库的根目录作为网站的根目录。这样做有一些好处,比如很容易实现网站的版本控制,部署起来也相对方便。而且,不光是静态页面,对于一些脚本类网站,这个方式也是很不错的。(jsp就别想了)。

那么如果我有一台服务器(Windows或是Linux),可以用来架设网站,那么是不是也能像github.io那样,随着版本库的更新而更新网站呢?答案是肯定的。且听我慢慢道来。

安装git服务器

首先要搭一个git服务器,这里我使用了gitblit,官网链接在 这儿 。作为git服务器,gitblit的功能还是很够用的,界面也不错。下面来实际安装一下(以Ubuntu为例):

下载,解压gitblit(前置需求jre):

wget http://dl.bintray.com/gitblit/releases/gitblit-1.7.1.tar.gz
mkdir gitblit
cp gitblit-1.7.1.tar.gz
cd gitblit/
gzip -d gitblit-1.7.1.tar.gz
tar xf gitblit-1.7.1.tar

打开 service-ubuntu.sh ,将以下变量进行适当的修改,使其指向当前的目录:

GITBLIT_PATH=/opt/gitblit
GITBLIT_BASE_FOLDER=/opt/gitblit/data
GITBLIT_USER="gitblit"

然后安装gitblit:

sudo install-service-ubuntu.sh
sudo service gitblit start

gitblit/data/gitblit.properties 文件里有以下内容,指定了http控制台的端口号:

git.daemonPort = 9418

gitblit/data/users.conf 文件里可以设置admin用户的密码。

所以此时我们就可以用服务器IP(或域名)和端口号来访问控制台了:
gitblit_welcome

配置网站路径

这里用了nginx作为网站服务器,这里只给出一个例子,不作详述。注意这里的网站根目录:

server {
	listen 80;
	server_name gittest.herbix.me;
	root "/home/datadir/www/gittest";
	location / {
		index index.html;
		allow all;
	}
	#include php.conf;
}

创建版本库

打开gitblit的控制台,登录,选择导航栏上的“版本库”,选择“新建版本库”。

gitblit_create

填入必要的信息之后(版本库名为gittest),点击“创建”,就建好了一个版本库。在版本库页面,点击右上角的“编辑”以编辑这个版本库的属性。在编辑页面,选择左边的“receive”选项卡。向下滚动,可以看到脚本选项:

gitblit_option

如说明所言,pre-receive scripts会在push请求生效前触发,post-receive scripts会在push请求生效后触发。仔细回想一下需求:要想通过git布署网站,只需在push完成后,将网站目录更新成版本库的内容。所以这里所需要的,就是一个脚本。

编写脚本

gitblit的脚本保存在 gitblit/data/groovy 目录下,用groovy语言编写。原本这里就有一些例子脚本。翻看一下,发现 localclone.groovy 最接近我们的需求,其内容如下:

// Indicate we have started the script
logger.info("localclone hook triggered by ${user.username} for ${repository.name}")
def rootFolder = 'c:/test'
def bare = false
def cloneAllBranches = true
def cloneBranch = 'refs/heads/master'
def includeSubmodules = true
def repoName = repository.name
def destinationFolder = new File(rootFolder, StringUtils.stripDotGit(repoName))
def srcUrl = 'file://' + new File(gitblit.getRepositoriesFolder(), repoName).absolutePath
// delete any previous clone
if (destinationFolder.exists()) {
	FileUtils.delete(destinationFolder, FileUtils.RECURSIVE)
}
// clone the repository
logger.info("cloning ${srcUrl} to ${destinationFolder}")
CloneCommand cmd = Git.cloneRepository();
cmd.setBare(bare)
if (cloneAllBranches)
	cmd.setCloneAllBranches(true)
else
	cmd.setBranch(cloneBranch)
cmd.setCloneSubmodules(includeSubmodules)
cmd.setURI(srcUrl)
cmd.setDirectory(destinationFolder)
Git git = cmd.call();
git.repository.close()
// report clone operation success back to pushing Git client
clientLogger.info("${repoName} cloned to ${destinationFolder}")

这个脚本是一个post-receive脚本,主要作用是将当前提交的版本库克隆到本地的某个目录下。如果这个目录下已经存在一个克隆好的版本库的话,就先删除之。对我们来说,这实在是太合适了,只需要将 def rootFolder = 'c:/test' 这句修改为 def rootFolder = '/home/datadir/www' 就好了(参考前面的nginx配置)。然后另存为一个脚本 depolywebsite.groovy

配置版本库

回到版本库的属性的编辑页面,选中我们新写的脚本,保存。

gitblit_done

推送一次版本库,看看网站是否更新了?果然是成功了。

后续

这个脚本虽然能用,但有一些问题。

所以只好改脚本了……

// Indicate we have started the script
logger.info("deploywebsite hook triggered by ${user.username} for ${repository.name}")
def repoName = StringUtils.stripDotGit(repository.name)
def websiteName = repoName.substring(repoName.lastIndexOf('/') + 1)
def rootFolder = '/home/datadir/www'
def srcUrl = 'file://' + new File(gitblit.getRepositoriesFolder(), repository.name).absolutePath
def destinationFolder = new File(rootFolder, websiteName)
def allBranches = true
def branch = 'refs/heads/master'
def includeSubmodules = true
if (destinationFolder.exists()) {
    logger.info("pulling from ${srcUrl} to ${destinationFolder}")
    Git git = Git.open(destinationFolder)
    PullCommand cmd = git.pull()
    cmd.setRemoteBranchName(branch)
    cmd.call()
    git.close()
} else {
    def bare = false
    // clone the repository
    logger.info("cloning ${srcUrl} to ${destinationFolder}")
    CloneCommand cmd = Git.cloneRepository();
    cmd.setBare(bare)
    if (allBranches)
        cmd.setCloneAllBranches(true)
    else
        cmd.setBranch(branch)
    cmd.setCloneSubmodules(includeSubmodules)
    cmd.setURI(srcUrl)
    cmd.setDirectory(destinationFolder)
    Git git = cmd.call();
    git.repository.close()
}
// report clone operation success back to pushing Git client
clientLogger.info("${repoName} deployed to ${destinationFolder}")

如何方便地改脚本

用IDE,我使用的是Intellij Idea,新建一个groovy工程,引入gitblit的库(存在gitblit/ext或gitblit/lib目录下,还有gitblit.jar),再在脚本的头部加入预定义变量:

com.gitblit.GitBlit                                   gitblit
com.gitblit.models.RepositoryModel                    repository
org.eclipse.jgit.transport.ReceivePack                receivePack
com.gitblit.models.UserModel                          user
Collection<org.eclipse.jgit.transport.ReceiveCommand> commands
String                                                url
org.slf4j.Logger                                      logger
com.gitblit.utils.ClientLogger                        clientLogger

修改脚本变得如此简单。当然,写完了以后别忘了去掉这些预定义变量。

作者:炒饭的小站
随意而为,不拘一格
原文地址:用git布署网站的方法, 感谢原作者分享。