MENU

使用Gogs配置git-hook部署代码

September 20, 2019 • GIT

在调研一个新项目的过程中需要使用 git 来提交修改代码,由于是调研阶段所以新项目代码没有使用公司的 gitlab 版本库。而是我自己搭建在了内网的一台测试服务器上面。所以就会用协同开发代码的拉取提交过程。

所以第一想法就是使用 git server 来简单的部署一个 git 服务器。在加上 git 自带的 hook 可以进行代码的自动提交部署。然而之前了解到一个比 gitlab 更加轻量的代码仓库 Gogs,而且常用的 gitlab 上的功能都有,最关键的是他是使用 Go 开发的,一个直接运行二进制文件部署,非常的方便。

如果不想使用 Gogs,你通用可以使用纯命令版本的部署方法,参考配置 git-hook 部署项目代码,原理都是一样的。只是 Gogs 提供的 web 版对新手还是挺友好的。

环境要求展开目录

Gogs 需要很少的环境依赖如下:

  • 数据库(选择以下一项):

    • MySQL:版本 >= 5.7
    • PostgreSQL
    • MSSQL
    • TiDB(实验性支持,使用 MySQL 协议连接)
    • 或者 什么都不安装 直接使用 SQLite3
  • git

    (bash):

    • 服务端和客户端均需版本 >= 1.7.1
    • Windows 系统建议使用最新版
  • SSH 服务器:

    • 如果您只使用 HTTP/HTTPS 的话请忽略此项
    • 如果您选择在 Windows 系统使用内置 SSH 服务器,请确保添加 ssh-keygen 到您的 %PATH% 环境变量中
    • 推荐 Windows 系统使用 Cygwin OpenSSHCopssh
    • Windows 系统 请确保 Bash 是默认的 Shell 程序,而不是 PowerShell

由于我是部署 PHP 项目,所以我直接使用了 MySQL,你也可以不用安装数据库,直接使用 SQLite3。(对于个人 SQLite3 还是没啥问题,如果是团队中正式使用还是推荐正式一点的数据库,比如 MySQL)

以下的操纵我都是使用的 CentOS7 操作,对于 Debian 或 Ubuntu 命令做对应的替换就好了

安装 git 展开目录

如果你的系统上没有 git,执行执行下面的命令安装即可。

  • yum install -y git

配置 git 用户展开目录

  1. 创建 git 用户

    我们使用专门的 git 用户来管理,而且我们以后生成的 clone 地址类似 git@wq.com:lepig/we7.git

    • useradd git

    密码可以先不用设置,因为我们后面主要是使用密钥的方式来提交代码。

    需要注意的是,我们不需要将 git 的登录 shell 修改为 /usr/bin/git-shell,保持默认的 /bin/bash 就好。因为 gogs 会自动会 git 用户的 shell 进行限制

    • ssh -T git@wq.com
    • Hi there, You've successfully authenticated, but Gogs does not provide shell access.
    • If this is unexpected, please log in with password and setup Gogs under another user.
  2. 创建证书登录文件 (authorized_keys)

    • cd /home/git/
    • sudo -u git mkdir .ssh
    • chmod 700 .ssh/
    • sudo -u git touch .ssh/authorized_keys
    • chmod 600 .ssh/authorized_keys

配置 Gogs 展开目录

  1. 安装 Gogs

    我使用的是二进制的部署方式,具体二进制文件可以到 Gogs 官网下载最新的版本。下载后得到一个压缩包 gogs_0.11.91_linux_amd64.zip

    解压后会得到一个 gogs 目录

    UlJA.png

    我们只要执行下面的命令就 OK 了

    • chown -R git:git gogs #给予git权限,不然无法启动服务
    • cd gogs
    • sudo -u git ./gogs web #推荐使用-u参数来指定使用git用户来操作
  2. 配置 Gogs

    如果你是第一次启动正常情况会出现下面的输出,就表示启动成功,然后访问你的 ip:3000 端口

    • [root@JDu4e00u53f7 gogs]# sudo -u git ./gogs web
    • 2019/09/19 18:25:32 [ WARN] Custom config '/home/git/gogs/custom/conf/app.ini' not found, ignore this if you're running first time
    • 2019/09/19 18:25:32 [TRACE] Custom path: /home/git/gogs/custom
    • 2019/09/19 18:25:32 [TRACE] Log path: /home/git/gogs/log
    • 2019/09/19 18:25:32 [TRACE] Log Mode: Console (Trace)
    • 2019/09/19 18:25:32 [ INFO] Gogs 0.11.91.0811
    • 2019/09/19 18:25:32 [ INFO] Cache Service Enabled
    • 2019/09/19 18:25:32 [ INFO] Session Service Enabled
    • 2019/09/19 18:25:32 [ INFO] SQLite3 Supported
    • 2019/09/19 18:25:32 [ INFO] Run Mode: Development
    • 2019/09/19 18:25:32 [ INFO] Listen: http://0.0.0.0:3000

    如果不出意外,你会被引导到 /install 页面,这里需要你填入相关的信息,包括数据库信息,这里如要看一下 “应用基本设置” 选项

    Upxh.png

    然后点击 “立即安装” 即可。安装完成后会跳转到登录页面,这时候你可以直接注册帐号,默认第一个用户就是管理员。

配置 git 仓库展开目录

  1. 配置用户 SSH 密钥

    首先点击头像右上角,然后点击 “用户设置”

其实上面配置好以后,如果你有使用过 github 的经验下面的基本上不是事。

我创建了一个 lepig/php 的新仓库,然后我们可以先配置一下用户的密钥,使得我们拉取和提交代码的时候不用输入密码。

UyW6.png

然后我们点击 “增加密钥” 按钮,把你自己的 ssh 可以配置进去。

ULfH.png

具体生成客户端密钥,请依次执行下面的命令(在你的本地开发电脑执行,而不是在服务器上,切记。

  • ssh-keygen -t rsa -C '注释'

然后一路回车到底就完事了。默认会在你的 $HOME/.ssh/ 目录下产生 2 个文件,分别是 id_rsaid_rsa.pub。请将 id_rsa.pub 文件中的内容复制到上面的输入框中。

  1. 拉取仓库

    Uh5p.png

    第一次通过 ssh 方式拉取的时候需要输入 yes 确认,以后都不需要了。这样就表示我们已经成功的把仓库拉取到本地了。然后可以 cd php 进入到代码目录提交一个文件试试。

    US1V.png

    Ur0j.png

配置 git 钩子展开目录

现在我们已经可以正常的进行代码的拉取提交了。但是我们怎么使得我们每次 push 代码的时候都会更新到我们的 web 项目呢???这个时候就要轮到 git hook 出场了。我们需要点击 “仓库设置” 里面的 “管理 Git 钩子” 选项了。

U0KW.png

​ 点击右边的 “编辑” 按钮,将下面命令粘贴进去

  • #!/bin/sh
  • unset GIT_DIR
  • DIR_ONE=/home/wwwroot/wq.com/ #此目录为服务器页面展示目录
  • cd $DIR_ONE
  • sudo -u www git reset --hard
  • sudo -u www git pull origin master

到此我们已完成大部分操作,还剩最后一步,配置 www 用户的部署密钥。

为什么要配置 www 用户的密钥?

因为我们的 php-fpm 是以 www 这个用户来执行的,所以 web 目录一般的所属用户和所属组都是 www,所以我要以 www 用户的身份来 pull 仓库代码。

同样,我们执行命令来创建 www 用户的公钥

  • sudo -u www ssh-keygen -t rsa -C "www@localhost"

然后我们将 /home/www/.ssh/id_rsa.pub 文件的内容先复制一下。然后点击 “仓库设置”->“管理部署密钥”,我们把刚刚复制的密钥粘贴进去。

然后我们去服务器上执行 sudo -u www git@116.196.95.135:lepig/php.git

UCIM.png

可能的报错展开目录

error: insufficient permission for adding an object to repository database .git/objects

如果出现这个错误,可能是 linux 权限导致的。进入到 web 目录 /home/wwwroot/php,然后执行 sudo chown -R www:www .git/objects 一般就可以解决

We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things:

​ #1) Respect the privacy of others.

​ #2) Think before you type.

​ #3) With great power comes great responsibility.

sudo: no tty present and no askpass program specified

如果出现上面类似的错误,是因为当使用 sudo 切换 git 用户的时候需要输入密码进行认证。那么我们场景中是在钩子中使用 sudo 切换 git 用户的。所以无法输入密码。这个时候我们可以使用 visudo 命令,在最后面加上一句

  • git ALL=(ALL) NOPASSWD: ALL

或者你可以可以把 git 用户加入到系统自带的 wheel 用户组中,这个组里的用户默认就不需要密码就可以进行用户切换。

或者你可以将 git 用户加入到系统自带的 wheel 用户组中,然后把这个组设置为 NOPASSWD 也是可以的。

%wheel ALL=(ALL) NOPASSWD: ALL

Last Modified: November 14, 2019
Leave a Comment

12 Comments
  1. 代码诗人 代码诗人

    Gogs 确实很好用,我们的小团队就一直在使用,轻量方便 @(大拇指)

  2. zsp zsp

    想问问您我在 push 出现了 cannot open .git/FETCH_HEAD: Permission denied 的错误,但是又在服务器的.git 目录下没有找到 FETCH_HEAD 这个文件。请问是什么问题呢

    1. @zsp 没有出现过这个错误。 你这个错误 说明 你没有 pull 过代码。 这个文件是 git fetch 的时候 自动生成的

    2. zsp zsp

      @花卷丶我在服务器端 pull 过后,生成了 git getch,但是在本地机还是显示 permission denied , 我已经给它赋予了权限,麻烦您帮忙看一下 -rw-rw-r-- 1 root root 106 Mar 10 18:49 FETCH_HEAD

    3. @zsp 你先给 777 权限试试。 你现在是用 root 用户来 push 或者 pull 的么?
      系统给了这个提示 就说明是当前操作用户没有拿到这个文件的权限

    4. zsp zsp

      @花卷丶因为我的网页路径在 root 下,所以想用 root 在进行 push 和 pll,可行吗?我给了 777 后发现不报 permission denied 了,开始报这个了 Could not create directory '/home/www/.ssh'.
      remote: Host key verification failed.
      remote: fatal: Could not read from remote repository.
      @(惊哭)

    5. @zsp 你的远程仓库 ssh 密钥用的是 www 的吧。这个报错现在是密钥不对,应该用 www 用户的密钥放到远程仓库。
      服务器上的目录权限 给 www 用户读写 (rw) 权限。

      以后这种 root 权限 最好别用。 危险挺大

    6. zsp zsp

      @花卷丶感谢您!我解决了,刚刚学习 linux 对这个用户管理还没什么概念,谢谢你的耐心解答!

    7. zsp zsp

      @花卷丶还有一个问题请教一下,就是 gogs 上用户管理的 ssh 密钥和 仓库上的部署密钥 有什么区别呢

    8. @zspSSH 密钥权限最大,各种操作都能做。 部署密钥只能用来做一些简单的 pull 操作。
      比如服务器一般都是从远程仓库 pull 代码,不会 push 代码。这个时候用部署公钥就比较合适。毕竟权限没那么大。就算服务器被黑,也不能对我们的仓库做毁灭性的操作。(只是我目前的理解,可能有其他的用途我目前还不清楚)@(太开心)

    9. zsp zsp

      @花卷丶豁然开朗! 感谢博主!

    10. @zsp 不用客气。相互学习。@(哈哈)