• 一、系统概述
  • 1、说明
  • 2、代码管理工具
  • 3、为什么是gogs?
  • 二、安装Gogs
  • 1、安装git
  • 2、环境配置
  • 3、安装Gogs
  • 1、下载gogs:
  • 2、解压和复制
  • 3、准备用户和仓库目录
  • 4、启动
  • 三、Gogs配置
  • 1、官方配置项
  • 2、 当前使用配置
  • 四、系统服务配置
  • 1、说明
  • 2、gogs.service配置
  • 3、通过systemctl启用gogs
  • 4、Nginx代理
  • 五、Gogs的API接口
  • 六、迁移其他平台仓库
  • 1、说明
  • 2、获取阿里云所有的仓库地址
  • 3、 编写python迁移脚本
  • 4、 执行迁移
  • 5、后续工作
  • 七、 使用约定
  • 1、 权限规定


一、系统概述

1、说明

  • 代码托管系统是开发中一个不可缺少的工具,通过代码托管系统可以方便协同开发,代码权限控制,代码异地灾备、版本管理、问题跟踪、项目文档管理等等项目管理所必须的工具。在项目的任何一个过程中,代码托管系统始终有着重要的地位。

2、代码管理工具

目前市面上开源的代码管理工具主要有两大体系:

  • SVN:集中式代码版本控制系统
  • GIT:分布式代码版本控制系统

集中式和分布式有其优缺点,简单而言,集中式需要一台中心服务器,中心服务器故障服务不可用,但是集中式对权限控制比较严格,粒度细,而分布式相反,它没有严格的中心服务器概念,托管系统服务器故障依然可以使用,但是权限控制相对较弱。

一般而言,开源的项目比较喜欢使用git

基于git和svn衍生出来的管理系统也有很多,例如基于git的github,阿里云code,码云等等,gitlab、Gogs也是其中之一,不同的是gitlab、gogs需要自己搭建,而github等以服务的形式提供给公众使用。

3、为什么是gogs?

  • 说到自建代码管理系统,首先想到的是gitlab,gitlab是基于ruby开发的一套功能丰富的代码管理系统,但是gitlab资源消耗异常大,在低配置的服务器中无法支撑大用户量的使用,安装维护也异常麻烦。 Gogs是基于go语言开发的开源代码管理系统,go语言有其天生的高并发高性能的特点,在低配置的服务器中也能支持大用户量愉快的玩耍,Gogs起步晚,功能没有gitlab丰富,但是提供了基本的功能,并且安装维护比gitlab更为简单方便,在我们的评估了gogs的功能以后得出结论完全符合我司的需要。 于是选择了gogs

二、安装Gogs

1、安装git

  • 安装gogs之前,必须要要先安装git,可以通过 yum install git 命令安装

2、环境配置

先准备好服务器。

3、安装Gogs

1、下载gogs:

[root@Gogs ~]# wget https://dl.gogs.io/0.11.43/gogs_0.11.43_linux_amd64.tar.gz  
--2018-04-03 15:31:02--  https://dl.gogs.io/0.11.43/gogs_0.11.43_linux_amd64.tar.gz 
Resolving dl.gogs.io (dl.gogs.io)... 138.68.27.161  
Connecting to dl.gogs.io (dl.gogs.io)|138.68.27.161|:443... connected.  
HTTP request sent, awaiting response... 200 OK  
Length: 19214809 (18M) [application/x-gzip]  
Saving to: 'gogs_0.11.43_linux_amd64.tar.gz'

100%[===========================================================>] 19,214,809   341KB/s   in 31s  

2018-04-03 15:31:34 (607 KB/s) - 'gogs_0.11.43_linux_amd64.tar.gz' saved [19214809/19214809]  
[root@Gogs ~]#

2、解压和复制

[root@Gogs ~]# tar -zxvf gogs_0.11.43_linux_amd64.tar.gz

将解压得到的文件夹复制到目标路径:

[root@Gogs ~]# cp -rf gogs /usr/local/gogs

解压得到的文件如下:

[root@Gogs ~]# cd /usr/local/gogs/  
[root@Gogs gogs]# ls   
gogs  LICENSE  public  README.md  README_ZH.md  scripts  templates  
[root@Gogs gogs]#
  • 其中 gogs 文件为启动命令
  • Public 为公共文件目录
  • Scripts 为脚本文件
  • Templates 为web的模版文件

3、准备用户和仓库目录

不建议使用root用户来运行gogs,我们准备一个用户用于运行gogs

[root@Gogs ~]# groupadd gogs  
[root@Gogs ~]# useradd -g gogs -s /bin/bash gogs  
[root@Gogs ~]# passwd gogs  
Changing password for user gogs.  
New password:   
Retype new password:   
passwd: all authentication tokens updated successfully.  
[root@Gogs ~]#

准备仓库目录和日志目录

[root@Gogs ~]# mkdir -p /data/gogs/repositories  
[root@Gogs ~]# mkdir -p /data/gogs/logs

修改相关文件权限

[root@Gogs ~]# chown -R gogs:gogs /data/gogs/  
[root@Gogs ~]# chown -R gogs:gogs /usr/local/gogs/

4、启动

启动前先切换到gogs用户

[root@Gogs ~]# su gogs  
[gogs@Gogs root]$ cd /usr/local/gogs/  
[gogs@Gogs gogs]$ ./gogs web  
2018/04/04 10:22:41 [ WARN] Custom config '/usr/local/gogs/custom/conf/app.ini' not found, ignore this if you're running first time  
2018/04/04 10:22:41 [TRACE] Custom path: /usr/local/gogs/custom  
2018/04/04 10:22:41 [TRACE] Log path: /usr/local/gogs/log  
2018/04/04 10:22:41 [TRACE] Log Mode: Console (Trace)  
2018/04/04 10:22:41 [ INFO] Gogs 0.11.43.0330  
2018/04/04 10:22:41 [ INFO] Cache Service Enabled  
2018/04/04 10:22:41 [ INFO] Session Service Enabled  
2018/04/04 10:22:41 [ INFO] SQLite3 Supported  
2018/04/04 10:22:41 [ INFO] Run Mode: Development  
2018/04/04 10:22:41 [ INFO] Listen: http://0.0.0.0:3000

如上,gogs已经启动了,启动信息直接打印在了屏幕,可以到gogs的各种信息,版本,路径,启动模式,监听端口等等。当然以上信息都是gogs的默认的,并不适合正式使用。我们后期在更改。

如上信息提示,gogs监听了一个3000端口,通过这个端口我们可以访问gogs的web服务。访问 http://ip:3000 或者 http://domain:3000 就可以了,首次访问会引导我们安装。

安装页面选项说明:

systemd 托管n9e_gogs安装手册

注意:
1、如果在安装页面没有配置管理员帐号,那么安装完成后点击注册按钮注册用户,用户ID为1的用户即为管理员。
2、情特别注意权限问题,gogs目录、仓库目录、日志目录请给足权限。

三、Gogs配置

1、官方配置项

2、 当前使用配置

我们使用如下配置

APP_NAME = GOGS代码托管平台  
RUN_USER = gogs  
RUN_MODE = prod  

[database]  
DB_TYPE  = mysql  
HOST     = 127.0.0.1:3306  
NAME     = gogs  
USER     = gogs  
PASSWD   = gogs@123  
SSL_MODE = disable  
PATH     = data/gogs.db  
[admin]  
DISABLE_REGULAR_ORG_CREATION = true  

[repository]  
ROOT = /data/gogs/repositories  
MAX_CREATION_LIMIT = 0  
ENABLE_LOCAL_PATH_MIGRATION = true  
FORCE_PRIVATE = true  
DISABLE_HTTP_GIT = false  

[server]  
DOMAIN           = git.example.com  
HTTP_PORT        = 3000  
ROOT_URL         = https://git.example.com/  
DISABLE_SSH      = false  
SSH_PORT         = 2222  
START_SSH_SERVER = true  
OFFLINE_MODE     = false  
ENABLE_GZIP      = true  

[mailer]  
ENABLED = false  

[service]  
REGISTER_EMAIL_CONFIRM = false  
ENABLE_NOTIFY_MAIL     = false  
DISABLE_REGISTRATION   = true  
ENABLE_CAPTCHA         = false  
REQUIRE_SIGNIN_VIEW    = false  

[picture]  
DISABLE_GRAVATAR        = true  
ENABLE_FEDERATED_AVATAR = false  

[session]  
PROVIDER = file  

[log]  
MODE      = file  
LEVEL     = Trace  
ROOT_PATH = /data/gogs/logs  

[security]  
INSTALL_LOCK = true  
SECRET_KEY   = QSL4Bv87UrgzZsK  
LOGIN_REMEMBER_DAYS = true  
COOKIE_USERNAME = true  
COOKIE_REMEMBER_NAME = true  
REVERSE_PROXY_AUTHENTICATION_USER = true  

[webhook]  
TYPES = gogs  
DELIVER_TIMEOUT = 300  
SKIP_TLS_VERIFY = true  
PAGING_NUM = true  

[cron]  
ENABLED = true

在如上配置中,我们启动了内置的SSH服务,并且不允许用户注册,用户也不允许创建仓库,具体请参考使用约定。

四、系统服务配置

1、说明

  • 通过运行 ./gogs web 可以启动gogs,但是此种启动方式并不是以 daemon 的方式运行,终端退出后gogs也就退出了,显然这不是我们想要的。 我们需要gogs在后台运行。

2、gogs.service配置

[Unit]  
Description=Gogs  
After=network.target  

[Service]  

Type=simple  
User=gogs  
Group=gogs  
WorkingDirectory=/usr/local/gogs  
ExecStart=/usr/local/gogs/gogs web
Restart=always  

[Install]  
WantedBy=multi-user.target

以上配置写入到 /usr/lib/systemd/system/gogs.service 文件。
如果使用的是本地的数据库,建议在After配置数据库启动后再启动gogs。

因为我们使用阿里云的RDS服务,可以不管。

要注意 usergroup 的配置,必须要和 gogs 的运行用户一致,否则启动失败,另外还需要关注git是否加入到环境变量中,如果没有可以通过Environment=传入环境变量

3、通过systemctl启用gogs

[root@Gogs gogs]# systemctl enable gogs.service  
Created symlink from /etc/systemd/system/multi-user.target.wants/gogs.service to /usr/lib/systemd/system/gogs.service.  
[root@Gogs gogs]# systemctl start gogs.service  
[root@Gogs gogs]# systemctl status gogs.service  
● gogs.service - Gogs  
   Loaded: loaded (/usr/lib/systemd/system/gogs.service; enabled; vendor preset: disabled)  
   Active: active (running) since Wed 2018-04-04 11:20:35 CST; 5s ago  
   Main PID: 2445 (gogs)  
   CGroup: /system.slice/gogs.service  
           └─2445 /usr/local/gogs/gogs web > /data/gogs/logs/output.log 2>&1 &  

Apr 04 11:20:35 Gogs systemd[1]: Started Gogs.  
Apr 04 11:20:35 Gogs systemd[1]: Starting Gogs...  
Apr 04 11:20:35 Gogs nohup[2445]: 2018/04/04 11:20:35 [TRACE] Custom path: /usr/local/gogs/custom  
Apr 04 11:20:35 Gogs nohup[2445]: 2018/04/04 11:20:35 [TRACE] Log path: /data/gogs/logs  
Apr 04 11:20:35 Gogs nohup[2445]: 2018/04/04 11:20:35 [TRACE] Log Mode: File (Trace)  
Apr 04 11:20:35 Gogs nohup[2445]: 2018/04/04 11:20:35 [ INFO] 最牛逼的代码管理平台 0.11.43.0330

如上,gogs以 daemon 的方式运行成功了。

4、Nginx代理

Gogs默认使用 3000 做为web的监听端口,因为权限的问题gogs无法创建1024以下的端口,具体原因可以自行百度谷歌搜索,不再这里展开了。 如果需要直接通过域名访问,我们还需要使用nginx做一下代理。Nginx做代理给我们带来两个好处:

  • 1、 可以使用域名直接访问,而不用加端口号。
  • 2、 可以配置SSL证书。

安装好nginx之后,添加如下配置:

server {  
        listen       80;  
        server_name  git.example.com;  

    rewrite ^(.*)$  https://$host$1 permanent;       
    }  

    # HTTPS server  

server {  
    listen       443 ssl;  
    server_name  git.example.com;  

    ssl_certificate      /etc/letsencrypt/live/git.example.com/fullchain.pem;  
    ssl_certificate_key  /etc/letsencrypt/live/git.example.com/privkey.pem;  

    ssl_session_cache    shared:SSL:1m;  
    ssl_session_timeout  5m;  

    ssl_ciphers  HIGH:!aNULL:!MD5;  
    ssl_prefer_server_ciphers  on;  

     location  / {  
            index  index.php index.html index.htm;  
            autoindex off;   
            proxy_set_header Host $host;  
            proxy_set_header X-Real-IP $remote_addr;  
            proxy_pass http://localhost:3000;  
            access_log  logs/git.access.log;  
         }  
    }

如上,所有http的访问都将跳转到https的访问。

Nginx的安装配置和证书的签证这里就不展开了,详情请参考《服务器SSL证书生成、配置、续约手册》

五、Gogs的API接口

Gogs提供了api接口,可以方便我们管理gogs,因API接口信息量大,详情请移步到 wiki

六、迁移其他平台仓库

1、说明

在gogs之前,我们使用的是阿里云的CODE,因为各种原因,我们迁移到了gogs。

阿里云CODE的迁移工作已经完成,这里记录如何迁移的过程以及迁移的脚本,以便于下一次遇到类似情况有得参考。

注意:在开始迁移之前必须先做以下两件事:

  • 1、先在配置文件中的 [repository] 配置项目中配置 ENABLE_LOCAL_PATH_MIGRATION = true 以开启运行迁移外部仓库的功能。
  • 2、管理员账户必须要在授权应用中生成令牌

2、获取阿里云所有的仓库地址

阿里云CODE没有提供API接口,无法通过API接口获取到帐号下面的所有仓库,有两个方法可以解决,一个是手动复制,另外一个通过python爬虫爬取,我们迁移的时候将近百个仓库,所以我用了爬虫,具体爬虫代码这里不详细展现,爬到的仓库的https链接存放在https_git.txt文件中,每行一个仓库。

3、 编写python迁移脚本

Python脚本如下:

# -*- coding: utf-8 -*-    

import urllib2  
import urllib  

f = open("/root/https_git.txt")  
for git_https in f.readlines():  
    clone_addr = git_https.replace("\n","").replace("\r","")  
    repo_name = git_https.split("/")[4].split(".")[0]  
    data='''{"clone_addr" : "%s",   
    "uid" : 1,  
    "repo_name" : "%s",  
    "auth_username" : "linuxops",  
    "auth_password" : "linuxops@2018",  
    "private" : true }'''%(clone_addr,repo_name)  

    url="http://localhost:3000/api/v1/repos/migrate?token=36d125718c911a4afcbbd409ac9d0ff0a6c44e4c"  
    headers={"User-Agent":"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",'Content-Type':'application/json'}  
    req=urllib2.Request(url,headers=headers,data=data)  
    resul=urllib2.urlopen(req)  
    print resul.read()

此脚本仅使用阿里云CODE ,如果想要迁移其他系统请修改clone_addr和repo_name的变量

4、 执行迁移

运行python脚本,如下创建成功会以json的格式返回信息。

[root@Gogs ~]# python git_migrate.py   
{"id":15,"owner":{"id":1,"login":"root","full_name":"","email":"linuxops@foxmail.com","avatar_url":"https://secure.gravatar.com/avatar/ba7fb301e420c8ea24fd9f942b817100?d=identicon","username":"root"},"name":"linuxops_admin_php","full_name":"root/linuxops_admin_php","description":"","private":false,"fork":false,"parent":null,"empty":false,"mirror":false,"size":275456,"html_url":"http://git.test.com:3000/root/linuxops_admin_php","ssh_url":"ssh://gogs@git.test.com:2222/root/linuxops_admin_php.git","clone_url":"http://git.test.com:3000/root/linuxops_admin_php.git","website":"","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"default_branch":"master","created_at":"0001-01-01T00:00:00Z","updated_at":"0001-01-01T00:00:00Z","permissions":{"admin":true,"push":true,"pull":true}}

自此,gogs基本迁移成功。

5、后续工作

Gogs和其他的托管系统一样,提供了一个wiki的功能,wiki也是一个仓库,命名的格式是仓库名加wiki。例如,一个仓库的名称是admin,存放仓库的目录名称为admin.git,这个仓库的wiki目录就是admin.wiki.git,每一个wiki也是一个仓库。

通过迁移功能迁移其他平台的库,如果其他平台库没有wiki或者没有提供wiki的功能,那么gogs对wiki的操作就会报错,可能没有生成wiki的库,也可能生成了,因为没有内容导致访问失败,这些都将会在web端体现为500错误。

要解决这个问题很简单,可以通过python遍历所有的库,如果没有wiki库,那么创建,并且吸入一个文件提交即可,如果存在wiki库,创建一个文件提交即可。

具体的python代码不再这里展示。

七、 使用约定

1、 权限规定

Gogs代码托管平台用于企业内部的代码管理,不对外,为了更好的管理我们约定如下:

服务配置:

  • 禁止用户注册。
  • 禁止创建仓库,只允许超级管理员能创建。
  • 不允许需要用户名和昵称(通过需要页面实现)

代码库管理:

  • 所有代码库都在一个组织下。
  • 禁止对组织授权,组织内只有超级管理员
  • 对需要权限的开发者,添加到协作者中,默认可写权限(可写权限包含了读写)
  • 分支管理中默认分支为master。
  • 开启对maste的分支保护,开启通过合并请求提交代码。
  • 开启对master的分支保护,开启限制推送代码成员,仅允许小组负责人推送到master

代码发布:

  • 发布前,负责人需要提交合并到master,并且负责对代码冲突解决和代码评审。
  • 涉及到版本更迭需要负责人打标签。
  • 无论是测试或是正式环境,只发布master分支的代码或者tag标签