前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP & Git 最简单的自动部署之二 Win系列服务器

PHP & Git 最简单的自动部署之二 Win系列服务器

作者头像
horsley
发布2022-08-16 11:23:54
4910
发布2022-08-16 11:23:54
举报

上一回介绍了看起来挺高上大的PHP+git自动部署,之前一直是在linux平台上面使用的,用着还挺顺利的,今天很蛋疼的要做某个项目在windows服务器上面的自动部署,然后就有坑了。首先git在windows上面就是个问题了。msysgit?那家伙凑合能用,但是还是很多问题,还是上次的脚本,会出现无返回无错误进程没有启动的问题,如果你出现了找不到路径,不是可执行文件等提示,你可以试下制定好git的绝对路径,反正我这还是不行。

我换着用PHP的执行命令的方法,exec/system/passthru/shell_exec反正都是不行,出现无返回无错误进程没有启动,试着中间再套一层bat来调用,进程是起来了,但是不知道出什么错误一直不能结束,也就一直阻塞着。用ProcessExp看一下其实msysgit还真是个复杂而蛋疼的东西,一个简单的git pull 他会启动超过5级子进程,目测是sh,用来初始化环境,然后再在里面跑git。

于是我很蛋疼的想,我再写一个别的exe,把运行git pull并取结果包装起来,然后再让php来调用这个exe?结果还是不行,折腾了一天,突然一想不如自立门户,然后多了几行代码,把这个小程序改成了监听某个端口,接收到请求就git pull并把返回写到response,这个东西在go里面不难实现,最后做成这个样子,简单粗暴,有效。

代码语言:javascript
复制
// gitpull project main.go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"time"
)

func gitPull(o *http.ResponseWriter) bool {
	git, err := exec.LookPath("git")
	if err != nil {
		fmt.Fprint(*o, "git not found!"+err.Error())
		return false
	}

	this, err := exec.LookPath(os.Args[0])
	if err != nil {
		fmt.Fprint(*o, "get excutable path error!"+err.Error())
		return false
	}

	err = os.Chdir(filepath.Dir(this))
	if err != nil {
		fmt.Fprint(*o, "chdir error!"+err.Error())
		return false
	}

	cmd := exec.Command(git, "pull")
	if os.Getenv("HOME") == "" && os.Getenv("HOMEDIRVE") != "" && os.Getenv("HOMEPATH") != "" {
		cmd.Env = []string{"HOME=" + os.Getenv("HOMEDIRVE") + os.Getenv("HOMEPATH")}
	}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Fprint(*o, err)
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		fmt.Fprint(*o, err)
	}
	err = cmd.Start()
	if err != nil {
		fmt.Fprint(*o, "run git error!"+err.Error())
		return false
	}
	go io.Copy(*o, stdout)
	go io.Copy(*o, stderr)
	cmd.Wait()

	fmt.Println("Finish autodeploy at " + time.Now().Format("2006-01-02 15:04:05"))
	return true
}

func main() {
	http.HandleFunc("/", entry)
	http.ListenAndServe(":8124", nil)
}

func entry(w http.ResponseWriter, r *http.Request) {
	if r.Header.Get("Authorization") == "" {
		w.Header().Set("WWW-Authenticate", "Basic realm=\"My Realm\"")
		http.Error(w, "Restrict area", http.StatusUnauthorized)
	} else if r.Header.Get("Authorization") == "Basic aG9yc2xleTpnaXQtcHVsbA==" { //horsley:git-pull
		gitPull(&w)
	}
}

这个程序实现的东西就是一个一个小的http server ,监听8124端口,有简单的http auth,auth通过了之后会调用gitPull,调用过程很复杂的样子,其实还好,他先是找到git的绝对路径,然后Chdir到文件所在目录(也就是说,最后这个程序编译出来,应该放在版本库根目录),然后执行git pull再返回响应。这已经挺完美了,但是还可能出现的一个问题是你的机器在防火墙之后。你开了8124端口外网访问不到怎么办?那还用80端口,还用上次的脚本,做一次中转,脚本里面执行的部分改成curl一下127.0.0.1:8124好了,记得带上auth。

另外提醒一点,这样把版本库放在web目录方便自动部署啥的,其实有安全性的问题,毕竟你有一些例如数据库密码你是硬编码在配置文件里面的,也在版本控制之中,简单地说,你要保护.git目录,最简单的办法RewriteRule ^..* – F

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013 年 12 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档