@dungan
2021-03-23T08:11:14.000000Z
字数 4983
阅读 123
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: Development
2020/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 project
chmod 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.pub
root@8.129.104.24's password:
Administrator@WIN2008R2 ~/.ssh
$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDG23sMdPIADNB9MG+uTZXnB...
接着手动执行下文件同步的命令,可以发现不用输入密码了:
rsync -avzu --exclude-from='{$projectPath}/.syncignore' {$projectPath} root@xxx.xxx.xxx.2:{$webRoot}
--exclude-from
选项设置了同步时忽略的文件,我们可以将被忽略的文件存在 .syncignore 中,例如:
storage
tests
.env
搭配supervisor可以以守护进程的方式运行gogs服务。
[program:gogs]
environment=HOME="/root",USER="root"
directory = /data/wwwroot/gogs
command=/data/wwwroot/gogs/gogs web
autostart=true
user=root
startsecs=10
autorestart=true
startretries=3
priority=999
redirect_stderr=true
stdout_logfile_maxbytes=20MB
stdout_logfile_backups = 20
killasgroup=false
stdout_logfile=/data/wwwlogs/supervisorlogs/gogs.out.log
stderr_logfile=/data/wwwlogs/supervisorlogs/gogs.err.log
启动该服务:
supervisorctl update && supervisorctl start gogs