[关闭]
@dungan 2021-03-23T08:11:14.000000Z 字数 4983 阅读 123

Linux

Gogs 部署教程


介绍

Gogo 是一款很很容易部署的git代码托管服务,相比GitLab 其非常轻量,同时提供了比较完备的功能。

安装

  1. [root@localhost] wget https://dl.gogs.io/$VERSION/gogs_$VERSION_$OS_$ARCH.tar.gz
  2. [root@localhost] tar -zxvf gogs_$VERSION_$OS_$ARCH.tar.gz

运行 Gogs 服务

  1. [root@localhost] cd gogs
  2. [root@localhost] ./gogs web
  3. ...
  4. 2020/09/23 08:47:15 [ INFO] Run mode: Development
  5. 2020/09/23 08:47:15 [ INFO] Listen on http://0.0.0.0:3000

从上面的日志输出看可以看到,Gogs 监听的端口的为 3000,这样就启动了 Gogs 服务,超级简单。

还可以守护进程的方式运行:

  1. nohup ./gogs web &

配置

自定义配置文件

Gogs 的默认配置都保存在安装目录下的 conf/app.ini,您永远不需要编辑它。

如果想自定义某些配置,只需要创建 custom/conf/app.ini 就可以!在 custom/conf/app.ini 文件中修改相应选项的值即可。

例如,需要改变仓库根目录的路径:

  1. [repository]
  2. ROOT = /home/jiahuachen/gogs-repositories

访问 /install 来完成首次配置

访问 HOST:3000/install 会打开一个控制面板。该面板中可以设置仓库目录,使用的数据库等等!

Nginx 反向代理

在 nginx.conf 文件中,将下面的 server 部分增加至 http 分区内并重载配置:

  1. server {
  2. listen 80;
  3. server_name git.xxx.cn;
  4. location / {
  5. proxy_pass http://localhost:3000;
  6. }
  7. }

Gogs 用户管理

当用户注册时 ID = 1 则会自动成为管理员,无需邮箱验证。默认管理员登录 Admin -> Users 面板并设置其它人员为管理员。通过安装页面注册的用户会自动成为管理员。

代码部署

webhook

你只需要在代码仓库中配置下你的 web 钩子就可以了。
hooks.png

web 钩子的 url 格式如下:

  1. http://www.xxx.cn/webhook.php?project=$projectName

$projectName 指的是代码仓库映射的服务器上的目录名。

webhook.php 内容如下:

  1. <?php
  2. // 记得修改 php.ini 的shell_exec
  3. $projectName = $_REQUEST['project'];
  4. $isFront = $_REQUEST['is_front'];
  5. $projectPath = "/data/wwwroot/{$projectName}";
  6. $hookLog = $projectName ? "{$projectPath}/webhook.log" : "/data/wwwroot/default/pullError.log";
  7. $branch = getBranch($projectPath);
  8. $pullCmd = pullCmd($branch, $projectPath);
  9. $buildCmd = "cd {$projectPath} && npm run build";
  10. // 日志删除(fileSize > $size || line > $num)
  11. shell_exec("unlink {$hookLog}");
  12. //项目名称不能为空
  13. if(empty($projectName))
  14. {
  15. shell_exec("echo 'Warning:请提供项目名称 !!!' >> {$hookLog}");
  16. show($hookLog);
  17. }
  18. //记录客户端信息
  19. $info = getClientInfo($projectName);
  20. shell_exec("echo '==================客户端信息==============\n' >> {$hookLog}");
  21. shell_exec("echo '{$info}' >> {$hookLog}");
  22. //拉取代码
  23. shell_exec("echo '==================拉取代码================\n' >> {$hookLog}");
  24. $res = shell_exec($pullCmd) .PHP_EOL.PHP_EOL;
  25. shell_exec("echo '{$res}' >> {$hookLog}");
  26. //编译前端代码
  27. if($isFront)
  28. {
  29. shell_exec("echo '==================编译代码================\n' >> {$hookLog}");
  30. $build = shell_exec($buildCmd) .PHP_EOL.PHP_EOL;
  31. shell_exec("echo '{$build}' >> {$hookLog}");
  32. }
  33. // 输出日志
  34. shell_exec("echo '==================结束===================\n' >> {$hookLog}");
  35. show($hookLog);
  36. /**
  37. * 客户端信息
  38. * @param $projectName
  39. * @return string
  40. */
  41. function getClientInfo($projectName)
  42. {
  43. $current = date("Y-m-d H:i:s");
  44. $clientIp = $_SERVER['REMOTE_ADDR'];
  45. $json = file_get_contents('php://input');
  46. $info = "project={$projectName}" . PHP_EOL;
  47. $info .= "地址={$clientIp},时间={$current}" . PHP_EOL;
  48. $info .= "data:{$json}" . PHP_EOL.PHP_EOL;
  49. return $info;
  50. }
  51. /**
  52. * 获取数据
  53. * @return false|string
  54. */
  55. function inputStream()
  56. {
  57. return file_get_contents('php://input');
  58. }
  59. /**
  60. * 获取分支
  61. * @param $projectPath
  62. * @return string|null
  63. */
  64. function getBranch($projectPath)
  65. {
  66. $arr = json_decode(inputStream(), true);
  67. $ref = explode('/', $arr['ref']);
  68. $branch = end(array_filter($ref));
  69. $current= shell_exec("cd {$projectPath} && git rev-parse --abbrev-ref HEAD");
  70. return $branch ?: $current;
  71. }
  72. /**
  73. * 分支拉取
  74. * @param $branch
  75. * @param $projectPath
  76. * @return string
  77. */
  78. function pullCmd($branch, $projectPath)
  79. {
  80. $isBranchExist = shell_exec("cd {$projectPath} && git branch | grep {$branch}");
  81. if($isBranchExist)
  82. {
  83. return $pullCmd = "cd {$projectPath} && git checkout {$branch} && git pull";
  84. }
  85. return $pullCmd = "cd {$projectPath} && git fetch origin && git checkout -b {$branch} origin/{$branch}";
  86. }
  87. /**
  88. * 输出
  89. * @param $hookLog
  90. */
  91. function show($hookLog)
  92. {
  93. echo '<pre>' . str_replace(PHP_EOL, '<br>', file_get_contents($hookLog));
  94. exit;
  95. }

webhook 引起的权限问题

www 用户的 .ssh 目录权限修改

home/www/.ssh 文件是属于root用户的。对于其它用户只有执行的操作,并没有读写操作。对于webhook.php 来说,执行用户是 www,因此需要修改/home/www/.ssh 目录的权限为 777,这样www用户就可以访问其公钥,拉取代码了。

记得将 www 的公钥添加到仓库登录账户中去。

  1. chmod 777 /home/www/.ssh

代码目录权限修改

由于调用webhook.php 时,执行用户为 www,因此对于代码目录也应做些权限修改。

  1. chown www.www -R project
  2. 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

脚本无法复现的问题,可以通过临时切换身份来发现问题。

  1. 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

内网 Git 代码部署到外网服务器

本质上在测试环境的 webhook.php 中通过 git 拉下来代码后,再将项目通过 scp/rsync 这类命令将项目同步到远程服务器。

为了避免文件传输时输入密码,需要将本机的 id_rsa.pub 中的公钥内容追加到远程云端服务器 .ssh/authorized_keys 文件中。

  1. ssh root@xxx.xxx.xxx.2 'cat >> .ssh/authorized_keys' < id_rsa.pub
  2. root@8.129.104.24's password:
  3. Administrator@WIN2008R2 ~/.ssh
  4. $ cat id_rsa.pub
  5. ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDG23sMdPIADNB9MG+uTZXnB...

接着手动执行下文件同步的命令,可以发现不用输入密码了:

  1. rsync -avzu --exclude-from='{$projectPath}/.syncignore' {$projectPath} root@xxx.xxx.xxx.2:{$webRoot}

--exclude-from 选项设置了同步时忽略的文件,我们可以将被忽略的文件存在 .syncignore 中,例如:

  1. storage
  2. tests
  3. .env

搭配 supervisor

搭配supervisor可以以守护进程的方式运行gogs服务。

  1. [program:gogs]
  2. environment=HOME="/root",USER="root"
  3. directory = /data/wwwroot/gogs
  4. command=/data/wwwroot/gogs/gogs web
  5. autostart=true
  6. user=root
  7. startsecs=10
  8. autorestart=true
  9. startretries=3
  10. priority=999
  11. redirect_stderr=true
  12. stdout_logfile_maxbytes=20MB
  13. stdout_logfile_backups = 20
  14. killasgroup=false
  15. stdout_logfile=/data/wwwlogs/supervisorlogs/gogs.out.log
  16. stderr_logfile=/data/wwwlogs/supervisorlogs/gogs.err.log

启动该服务:

  1. supervisorctl update && supervisorctl start gogs
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注