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.
    1. 创建证书登录文件(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用户来操作
    1. 配置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不用客气。相互学习。@(哈哈)