随着大微软收购GitHub,GitHub网站正式发博文以及公关稿,这个事件已经尘埃落定。

恭喜GitHub不用再烧投资人的钱,也恭喜微软云服务有了更好的硬实力之外,普通开发者可能需要考虑一下你的代码数据该怎么存放了:建设备份?进行迁移?自建服务?…

关于GitHub被收购一事完整看法

我个人观点在知乎已经写过:

原始答案

  1. 对于普通开发者影响不大,该查资料查资料,该提交提交,但是请注意资源备份,合规方面估计会删除一部分敏感资源(仓库提交多个origin,或者搞个仓库mirror是合理的)。
  2. 对于做开源影响力的某些大公司可能有一些影响,未来品牌运营不会单纯锁定做GH,估计会议和自由品牌会多一些,国内接下来也会有一波GitHub友商出现营销圈地拉人。
  3. 对于基于GitHub做一些业务的公司可能有一些影响,尤其是有一些业务领域有利益相关的情况。
  4. 对于一些hacker不是好事,版权问题相关,poc,exploit可能会越来越少。

不过个人看到情况:

  1. 个人开发者有敏感信息的不多,适当备份代码是必要的,只要代码还有一些价值。(和star无关,和你个人相关)
  2. 国内国外不少公司,有自己的开源品牌体系,开源代码托管有不少竞品,bitbucket,gitlab等等。
  3. 越来越多的公司内部会自己托管代码仓库,而非寄人篱下,业务敏感特性决定。
  4. 圈子本来就在朝着私密化发展。

至于网上有人无脑传播GitLab服务的事情,早些时候,记得GitLab有说过他们要拥抱GKE,尤其是看着GitLab最近几个大版本的改变,迁移是迟早的事情,不需要过度解读和恐慌。4月份官方博客迁移声明

数据迁移、备份

GitLab在新项目创建的地方,很显眼的设置了GitHub迁移的操作界面,如果你想做一份备份,只需要点一下按钮,耐心等待GitLab把GitHub上的仓库Clone完毕就好。

只不过GitHub已经不完全是代码仓库服务了,上面更有价值的是“代码社交”:

  • issue讨论设施
  • contributor共建文化
  • 甚至是commit activity和commit history timeline

如果你的目的是专注开发软件,又不太想进行代码托管服务的维护的话,迁移数据或者备份数据是一个不错的选择。

未来你的项目是否会因为敏感词或者协议或者合规问题被改动乃至被迫404掉,现在下断言还太早了,不好说。

架设你自由的代码仓库服务

如果你觉得数据假手于人不靠谱,对自己的运维能力有一定的信心,或者想顺便学习这方面的知识,可以考虑自己运维一套代码数据仓库,借助docker的力量,网速快的话,几分钟之内你就能够拥有一套私有的代码仓库服务。

不考虑一上来就付费购买全套商业技术设施的话,我们可以选择使用 GitLab 或者 Gogs。

自建 GitLab 代码仓库服务

说起GitLab,忘记是12年还是13年,新浪云开始进行SVN->Git的迁移,我的入门师傅世江当时找了一个2G内存的虚拟机安装了一套6.x版本的GitLab,因为是内网服务+底层是Git,响应速度超级快,比SVN整体体验不知道好多少倍,当时第一个想法就是我也要搞一套做实验玩!

当时还没有类似Docker的轻量虚拟化技术,预期用重虚拟化技术,不如直接用虚拟机,于是我的机器上常年开一个Bitnami提供的GitLab虚拟机,我记得版本是7.2,界面很清爽,没有学习GitHub的用户动态时间轴,十分清爽。

后面去淘宝,阿里上市前夕进行了技术升级,也开始把SVN往Git进行迁移,选型还是GitLab,于是坚定了机器上继续跑一套GitLab作为个人实验田的想法,期间把虚拟机里的应用从VMware迁移到VMBox再到Parallels,再迁移回来…得益于GitLab社区资源不少,配套的备份命令行也十分好用,从来没有出过问题,自此路转粉。

后面折腾家用服务器,期望能玩一套类似slack的全自动持续集成模式,又开始折腾GitLab的CI/CD,这是后话,扯远了,先说回主题:如何搭建一套你自己的GitLab仓库服务。

下面提供一份配置,基于GitLab官方fat image进行配置调用,包含了如何使用page服务,以及使用http2进行网站访问服务。

配置中的域名可以修改为你自己的域名,可以是公网注册的域名,也可以是你自己想要的各种域名,记得修改你的网络DNS指向就好。

比如腾讯内部有广泛使用的oa.com,阿里内部各种使用的alibaba/alipay.net,你喜欢的话,大可以搞一个code.io之类的域名玩。

这里没有提供prometheus配置,这块比较坑,后面再提。

version: '2'  

services:

  gitlab:
    restart: always
    image: 'gitlab/gitlab-ce:10.7.3-ce.0'
    hostname: 'gitlab.yourdomain.com'
    ports:
      - "80:80"
      - "443:443"
      - "22:22"
      - "9005:9999" # Nginx
    volumes:
      - './config:/etc/gitlab'
      - './logs:/var/log/gitlab'
      - './data:/var/opt/gitlab'
      - './cert/yourdomain.com.crt:/etc/gitlab/ssl/yourdomain.com.crt:ro'
      - './cert/yourdomain.com.key:/etc/gitlab/ssl/yourdomain.com.key:ro'
      - './cert/yourdomain.com.crt:/etc/gitlab/ssl/registry.gitlab.yourdomain.com.crt:ro'
      - './cert/yourdomain.com.key:/etc/gitlab/ssl/registry.gitlab.yourdomain.com.key:ro'
      - './cert/yourdomain.com.crt:/etc/gitlab/ssl/page.yourdomain.com.crt:ro'
      - './cert/yourdomain.com.key:/etc/gitlab/ssl/page.yourdomain.com.key:ro'
      - './cert/yourdomain.com.crt:/etc/gitlab/ssl/pages-nginx.crt:ro'
      - './cert/yourdomain.com.key:/etc/gitlab/ssl/pages-nginx.key:ro'
      - './cert/yourdomain.com.crt:/var/opt/gitlab/registry/certificate.crt:ro'
      - './embedded-logs:/opt/gitlab/embedded/logs/'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.yourdomain.com'
        gitlab_rails['time_zone'] = 'Asia/Shanghai'
        gitlab_rails['gitlab_default_projects_features_issues'] = true
        gitlab_rails['gitlab_default_projects_features_merge_requests'] = true
        gitlab_rails['gitlab_default_projects_features_wiki'] = true
        gitlab_rails['gitlab_default_projects_features_snippets'] = true
        gitlab_rails['gitlab_default_projects_features_builds'] = true
        gitlab_rails['gitlab_default_projects_features_container_registry'] = true
        mattermost['localization_server_locale'] = "zh_CN"
        mattermost['localization_client_locale'] = "zh_CN"
        mattermost['localization_available_locales'] = "en,zh_CN,ja"
        gitlab_rails['lfs_enabled'] = true
        registry_external_url 'https://registry.gitlab.yourdomain.com/'
        gitlab_rails['registry_enabled'] = false
        prometheus_monitoring['enable'] = false
        node_exporter['enable'] = false
        redis_exporter['enable'] = false
        postgres_exporter['enable'] = false
        gitlab_monitor['enable'] = false
        registry['enable'] = false
        nginx['enable'] = true
        nginx['client_max_body_size'] = '250m'
        nginx['redirect_http_to_https'] = true
        nginx['redirect_http_to_https_port'] = 80
        nginx['ssl_certificate'] = "/etc/gitlab/ssl/yourdomain.com.crt"
        nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/yourdomain.com.key"
        nginx['ssl_ciphers'] = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"
        nginx['ssl_prefer_server_ciphers'] = "on"
        nginx['ssl_protocols'] = "TLSv1.2"
        pages_external_url "https://page.yourdomain.com/"
        pages_nginx['ssl_certificate'] = "/etc/gitlab/ssl/pages-nginx.crt"
        pages_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/pages-nginx.key"
        gitlab_pages['enable'] = true
        gitlab_pages['inplace_chroot'] = true
        gitlab_pages['redirect_http'] = false
        gitlab_pages['use_http2'] = true
        gitlab_pages['dir'] = "/var/opt/gitlab/gitlab-pages"
        gitlab_pages['log_directory'] = "/var/log/gitlab/gitlab-pages"
        gitlab_pages['artifacts_server'] = true
        gitlab_pages['artifacts_server_timeout'] = 10
        nginx['http2_enabled'] = true
        nginx['proxy_set_headers'] = {
          "X-Forwarded-Proto" => "http",
          "CUSTOM_HEADER" => "VALUE"
        }
        nginx['status'] = {
          "listen_addresses" => ["127.0.0.1"],
          "fqdn" => "gitlab.yourdomain.com",
          "port" => 9999,
          "options" => {
            "stub_status" => "on", # Turn on stats
            "access_log" => "on", # Disable logs for stats
            "allow" => "127.0.0.1", # Only allow access from localhost
            "deny" => "all" # Deny access to anyone else
          }
        }        

将配置保存成你喜欢的文件名之后,执行docker-compose -f 你的文件名称 up,如果80,442,22,9005这几个端口没有占用的话,用不了一会你就能够看到属于你的gitlab已经运行起来了,如果你觉得这个软件还不错,可以使用 docker-compose -d命令再次运行,将它注册成为自动启动后台服务。(截止发文,新版本的docker在系统中安装完毕,已经能够自动启动)

顺便提一下,默认安装的docker是没有docker-compose这个编排工具的,你可以从这里获取到它: docker-compose 发布页面

以暂时最新的1.21.2为例,输入一下命令进行下载以及权限授予即可:

curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

这里说一个误区,如果你是GitLab早期用户、群晖Docker用户、可能会使用sameersbn/gitlab这个docker镜像,实际上早在一年前,官方就退出了自己的镜像,相比较三方镜像:更新更快,出现问题到官方社区得到支持的可能性也更大。

之前使用的过程中就曾经出现过几个问题:

  • pages服务疯狂写log,吃磁盘。
  • dockerhub服务疯狂重启,吃CPU。
  • 历史记录过多,在线rebase把机器拖死。
  • worker因为时区不对,执行时机诡异。

但是官方很快在一个个小版本更新中就把这个问题修复了,而三方镜像的维护方那边却堆了一堆issue和小白。

如果你要进行备份,可以在宿主机器执行 docker exec -t 你的GitLab容器名称 gitlab-rake gitlab:backup:create,然后把你的备份数据包妥善保存就可以了。

最后说一句,GitLab对系统资源要求比较高,2核心4GB能够让它跑的相对流畅,配置再低估计会遇到很多奇怪的OOM自杀进程问题,别问我为什么知道这个事情…

关于GitLab还有许多可以聊的事情,之后可以用它把前面没聊完的CI/CD的事情讲一讲。

轻量服务 Gogs

如果把 GitLab 比作大象来说,Gogs会是一只小鸟,体型虽小,五脏俱全,据说有不少初期的团队再用它做内部技术设施。

安装和配置Gogs不建议使用容器化方案,因为使用Go编写,而且只专注解决最基本的代码仓储的问题,你下载预编译好的软件包,在你的系统上运行就好了(记得启动一个守护软件)。

如果你想找寻适合你的更多的安装方式,可以参考:官方软件安装文档

如果你想把你的代码像是用GitHub一样的对外提供展示,又没有使用GitHub的服务的话,使用GitLab存在一定的安全隐患(软件复杂后不可避免),那么使用gogs会是一个好的选择,一台vultr 2.5$一个月的服务器就能跑的很流畅。

当然,如果你家里有老的笔记本,或者家用服务器,也可以跑在你的家用服务器上,通过ngrok、frp之类的软件映射到外网(同样需要一台外部服务器),如果想玩的话,可以参考我之前写过的一篇博客: 使用私有CI构建GitHub仓库 中的frp的操作。

最后

看了一眼表,该去吃饭了,先写到这里,如果你对本篇文章的内容有疑问或者想讨论,欢迎联系我,我的联系方式聪明的你应该找的到吧?

–EOF