最近比较喜欢用bitbucket,因为要用私有库又不舍得交钱给Github只能这样了,虽然自己也用gitolite搭了git server,但是毕竟仅仅是一个git server。
回到正题,之前的玩法都是开着putty,本地编辑好提交好push上去bitbucket/github,然后putty里面在原地git pull,今天突然想到能不能利用hook简单做个自动部署,稍微看了一下bitbucket的hook文档,bitbucket有个简单的Post Hook(github也有类似的),其实简单的利用这个,都不用出来post过来的关于提交的数据,直接pull就好,于是就有了下面的脚本
代码语言:javascript复制<?php
/**
* 简单自动部署
* bitbucket POST hook http://horsley:anypassword@your_host/autodeploy.php
*/
define('APP_PATH', dirname(__FILE__));
if (php_sapi_name() != 'cli') {
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
die('Restricted Area!');
} else {
if (($_SERVER['PHP_AUTH_USER'] != 'horsley') ||
($_SERVER['PHP_AUTH_PW'] != 'anypassword')
) {
die('Authentication Failed.');
}
}
}
if (file_exists(APP_PATH.'/_before_deploy.php')) {
echo "====== Tasks before update ======n";
require(APP_PATH.'/_before_deploy.php');
}
echo "nn====== Now update the repo ======n";
chdir();
system('git pull');
if (file_exists(APP_PATH.'/_after_deploy.php')) {
echo "nn====== Tasks after update ======n";
require(APP_PATH.'/_after_deploy.php');
}
然后在仓库的设置那边加个hook,注意看我这里加了简单的http auth,bitbucket是支持的。
这样完事之后发现还不行,因为默认php执行的httpd运行账户是www,一般为了安全都会把web运行账户弄得不能shell登陆(/sbin/nologin或者/bin/false),而且连home目录都没有,为了实现自动部署最好给www一个home,里面要放keys什么的。[11.5补充] 还最好为www用户config一下email和username,不然像bitbucket会说empty ident而无法pull [11.18补充]根据这里,empty ident的问题也可能是因为passwd里面第5个字段为空,最好在第5字段填上东西,是啥不重要
因为httpd什么的都在跑,直接usermod -d肯定说用户已登录改不了,这时候可以用vipw直接修改/etc/passwd,找到没有home(或者home是/dev/null什么的)的可怜的www,给一个home目录给他,shell不用改,保存退出会提示你可以vipw -s来改/etc/shadow保持一致性,这里只改了个home就不必了,后面执行命令可以直接sudo -u www 加命令来以www身份运行。
先sudo -u www mkdir ~/.ssh吧,然后sudo -u www ssh-keygen随便生成个key,不要设置密码,不然git pull困难还得请ssh-agent。生成之后吧id_rsa.pub cat出来加到仓库的部署key,部署key只有只读权限还是挺安全的。
好了之后你可以sudo -u www git pull测试能不能正常pull,能不能pull到,最好这样试一次,因为这里还有个交互是第一次访问要把对方加到known_host里面的,要回答yes,好了之后应该能pull到,web上面的php应该也能调用到git pull并返回信息。这里php后面可以再加别的东西例如针对自动部署的环境做的一些适应性修改、导数据库等工作,注意不要弄出conflict导致下次git pull困难就行。
我喜欢这样随随便便的写,长篇大论的博文我自己都不大愿意看,特别是没干货的东西