@dungan
2021-03-23T08:11:14.000000Z
字数 4983
阅读 134
Linux
Gogo 是一款很很容易部署的git代码托管服务,相比GitLab 其非常轻量,同时提供了比较完备的功能。
[root@localhost] wget https://dl.gogs.io/$VERSION/gogs_$VERSION_$OS_$ARCH.tar.gz[root@localhost] tar -zxvf gogs_$VERSION_$OS_$ARCH.tar.gz
[root@localhost] cd gogs[root@localhost] ./gogs web...2020/09/23 08:47:15 [ INFO] Run mode: Development2020/09/23 08:47:15 [ INFO] Listen on http://0.0.0.0:3000
从上面的日志输出看可以看到,Gogs 监听的端口的为 3000,这样就启动了 Gogs 服务,超级简单。
还可以守护进程的方式运行:
nohup ./gogs web &
Gogs 的默认配置都保存在安装目录下的 conf/app.ini,您永远不需要编辑它。
如果想自定义某些配置,只需要创建 custom/conf/app.ini 就可以!在 custom/conf/app.ini 文件中修改相应选项的值即可。
例如,需要改变仓库根目录的路径:
[repository]ROOT = /home/jiahuachen/gogs-repositories
访问 HOST:3000/install 会打开一个控制面板。该面板中可以设置仓库目录,使用的数据库等等!

在 nginx.conf 文件中,将下面的 server 部分增加至 http 分区内并重载配置:
server {listen 80;server_name git.xxx.cn;location / {proxy_pass http://localhost:3000;}}
当用户注册时 ID = 1 则会自动成为管理员,无需邮箱验证。默认管理员登录 Admin -> Users 面板并设置其它人员为管理员。通过安装页面注册的用户会自动成为管理员。
你只需要在代码仓库中配置下你的 web 钩子就可以了。

web 钩子的 url 格式如下:
http://www.xxx.cn/webhook.php?project=$projectName
$projectName指的是代码仓库映射的服务器上的目录名。
webhook.php 内容如下:
<?php// 记得修改 php.ini 的shell_exec$projectName = $_REQUEST['project'];$isFront = $_REQUEST['is_front'];$projectPath = "/data/wwwroot/{$projectName}";$hookLog = $projectName ? "{$projectPath}/webhook.log" : "/data/wwwroot/default/pullError.log";$branch = getBranch($projectPath);$pullCmd = pullCmd($branch, $projectPath);$buildCmd = "cd {$projectPath} && npm run build";// 日志删除(fileSize > $size || line > $num)shell_exec("unlink {$hookLog}");//项目名称不能为空if(empty($projectName)){shell_exec("echo 'Warning:请提供项目名称 !!!' >> {$hookLog}");show($hookLog);}//记录客户端信息$info = getClientInfo($projectName);shell_exec("echo '==================客户端信息==============\n' >> {$hookLog}");shell_exec("echo '{$info}' >> {$hookLog}");//拉取代码shell_exec("echo '==================拉取代码================\n' >> {$hookLog}");$res = shell_exec($pullCmd) .PHP_EOL.PHP_EOL;shell_exec("echo '{$res}' >> {$hookLog}");//编译前端代码if($isFront){shell_exec("echo '==================编译代码================\n' >> {$hookLog}");$build = shell_exec($buildCmd) .PHP_EOL.PHP_EOL;shell_exec("echo '{$build}' >> {$hookLog}");}// 输出日志shell_exec("echo '==================结束===================\n' >> {$hookLog}");show($hookLog);/*** 客户端信息* @param $projectName* @return string*/function getClientInfo($projectName){$current = date("Y-m-d H:i:s");$clientIp = $_SERVER['REMOTE_ADDR'];$json = file_get_contents('php://input');$info = "project={$projectName}" . PHP_EOL;$info .= "地址={$clientIp},时间={$current}" . PHP_EOL;$info .= "data:{$json}" . PHP_EOL.PHP_EOL;return $info;}/*** 获取数据* @return false|string*/function inputStream(){return file_get_contents('php://input');}/*** 获取分支* @param $projectPath* @return string|null*/function getBranch($projectPath){$arr = json_decode(inputStream(), true);$ref = explode('/', $arr['ref']);$branch = end(array_filter($ref));$current= shell_exec("cd {$projectPath} && git rev-parse --abbrev-ref HEAD");return $branch ?: $current;}/*** 分支拉取* @param $branch* @param $projectPath* @return string*/function pullCmd($branch, $projectPath){$isBranchExist = shell_exec("cd {$projectPath} && git branch | grep {$branch}");if($isBranchExist){return $pullCmd = "cd {$projectPath} && git checkout {$branch} && git pull";}return $pullCmd = "cd {$projectPath} && git fetch origin && git checkout -b {$branch} origin/{$branch}";}/*** 输出* @param $hookLog*/function show($hookLog){echo '<pre>' . str_replace(PHP_EOL, '<br>', file_get_contents($hookLog));exit;}
home/www/.ssh 文件是属于root用户的。对于其它用户只有执行的操作,并没有读写操作。对于webhook.php 来说,执行用户是 www,因此需要修改/home/www/.ssh 目录的权限为 777,这样www用户就可以访问其公钥,拉取代码了。
记得将 www 的公钥添加到仓库登录账户中去。
chmod 777 /home/www/.ssh
由于调用webhook.php 时,执行用户为 www,因此对于代码目录也应做些权限修改。
chown www.www -R projectchmod 755 project
git pull报错 error: cannot open .git/FETCH_HEAD:Permission denied。
这是由于 .git/FETCH_HEAD 的用户是root,但我们通过webhook.php 拉取代码时,用户是 www,因此需要对当前项目的用户修改:chown -R www.www project
脚本无法复现的问题,可以通过临时切换身份来发现问题。
sudo -Hu www git clone git@192.168.101.253:79016357/api.git
ssh:Permissions 0644 for ‘/root/.ssh/id_rsa’ are too open。
这是由于 root 用户的 ssh 私有密钥的权限开放尺度太大了,ssh 自身的策略关闭了ssh。
可以修改下 id_rsa 的权限来解决该问题:chmod 0600 /root/.ssh/id_rsa
本质上在测试环境的 webhook.php 中通过 git 拉下来代码后,再将项目通过 scp/rsync 这类命令将项目同步到远程服务器。
为了避免文件传输时输入密码,需要将本机的 id_rsa.pub 中的公钥内容追加到远程云端服务器 .ssh/authorized_keys 文件中。
ssh root@xxx.xxx.xxx.2 'cat >> .ssh/authorized_keys' < id_rsa.pubroot@8.129.104.24's password:Administrator@WIN2008R2 ~/.ssh$ cat id_rsa.pubssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDG23sMdPIADNB9MG+uTZXnB...
接着手动执行下文件同步的命令,可以发现不用输入密码了:
rsync -avzu --exclude-from='{$projectPath}/.syncignore' {$projectPath} root@xxx.xxx.xxx.2:{$webRoot}
--exclude-from 选项设置了同步时忽略的文件,我们可以将被忽略的文件存在 .syncignore 中,例如:
storagetests.env
搭配supervisor可以以守护进程的方式运行gogs服务。
[program:gogs]environment=HOME="/root",USER="root"directory = /data/wwwroot/gogscommand=/data/wwwroot/gogs/gogs webautostart=trueuser=rootstartsecs=10autorestart=truestartretries=3priority=999redirect_stderr=truestdout_logfile_maxbytes=20MBstdout_logfile_backups = 20killasgroup=falsestdout_logfile=/data/wwwlogs/supervisorlogs/gogs.out.logstderr_logfile=/data/wwwlogs/supervisorlogs/gogs.err.log
启动该服务:
supervisorctl update && supervisorctl start gogs