Go 私网开发服务搭建记录

2019/10/29

本文记录了私网 Go 开发所需的所有相关服务,包括版本管理,模块代理,持续集成。

涉及服务如下:

系统配置:

版本管理

目的

搭建版本管理系统(VCS)的目的:一方面是为私有项目提供版本管理,一方面是托管修改过的开源项目。

选型

私网环境开发,项目源码可以托管于任何版本管理系统,但是 Go 对 Git 的支持更好,优先考虑搭建 Git 服务作为版本管理。

Go 要求版本管理系统实现 go-get 接口。我们选择了 Gogs 。它是由 Go 语言编写的开源 Git 服务,搭建十分便捷 。

部署

详见 官方搭建指南 ,以下仅作记录。

如果使用 MySQL ,要求版本不低于 5.7 。参考这篇 安装 MySQL 8.0

新建数据库

名称: gogs

编码: utf8mb4

数据库中通过以下脚本新建数据库:

CREATE DATABASE gogs CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

下载最新二进制程序包

下载官网提供的二进制文件。

wget https://cdn.gogs.io/0.11.91/gogs_0.11.91_linux_amd64.tar.gz

解压运行

tar xf gogs_0.11.91_linux_amd64.tar.gz
cd gogs
./gogs web

按照提示进行配置

配置前确保 Git 已安装

安装 Git
sudo yum -y install git

浏览器访问当前主机的 3000 端口,开始配置。

有几个配置项需要注意:

配置守护进程

修改 ./scripts/systemd/gogs.service

[Unit]
Description=Gogs
After=syslog.target
After=network.target
After=mysqld.service

[Service]
LimitMEMLOCK=infinity
LimitNOFILE=65535
Type=simple
User=root
Group=root
WorkingDirectory=/home/shank/gogs
ExecStart=/home/shank/gogs/gogs web
Restart=always
Environment=USER=shank HOME=/home/shank

ProtectSystem=full
PrivateDevices=yes
PrivateTmp=yes
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target

注意修改为实际的用户目录

复制到系统目录

sudo cp ./scripts/systemd/gogs.service /usr/lib/systemd/system/

启用守护进程

sudo systemctl enable gogs
sudo systemctl start gogs

模块代理

目的

Go 1.11 之后推荐使用 go mod 作为依赖管理,使用 go mod 可以通过配置模块代理服务加快依赖包的下载。这类代理服务通过环境变量 GOPROXY 进行指定,只要实现了模块代理协议(Module proxy protocol)的服务都称为模块代理服务。

因为公有网络的不确定性(比如开源作者删除了代码仓库或者网络被防火墙劫持),可以考虑自己维护一个代理服务,方便私网内构建时拉取常用第三方代码依赖。

选型

目前有许多开源项目实现了 goproxy 服务,我们选择了社区活跃且版本稳定的 goproxyio/goproxy

源码构建及部署

Go 版本不低于 1.11

配置 Go 1.13.3 编译环境
wget https://dl.google.com/go/go1.13.3.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.13.3.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> $HOME/.profile
source $HOME/.profile
安装 make
sudo yum -y install make

下载一份稳定版版本的源码

wget https://github.com/goproxyio/goproxy/archive/v2.0.1.tar.gz

v2.0.0 版本有 BUG 。 我遇到如下问题 go get golang.org/x/tools/cmd/present: no matching versions for query "upgrade" 。 故此处已更新。

解压 & 编译

tar xf v2.0.1.tar.gz
cd goproxy-2.0.1
make

如果你使用的是 go 1.13 以下版本, make 可能因网络问题耗时严重,你需要设置环境变量 GOPROXY 加速构建,例如: export GOPROXY=https://goproxy.io。因为 go 1.13 指定了默认的 GOPROXY 可以不需要另外配置。

添加二进制文件到系统目录

sudo cp ./bin/goproxy /usr/local/bin

配置守护进程

修改 ./scripts/goproxy.service

[Unit]
Description=goproxy service
Documentation=https://goproxy.io
After=network-online.target

[Service]
User=root
Group=root
LimitNOFILE=65536
Environment=PATH=/usr/bin:/usr/local/go/bin
Environmnet=GO111MODULE=on
ExecStart=/usr/local/bin/goproxy -listen=0.0.0.0:8081 -proxy=https://goproxy.io -exclude=go.findshank.com
KillMode=control-group
SuccessExitStatus=2
Restart=always

[Install]
WantedBy=multi-user.target
Alias=goproxy.service

参数说明

复制到系统目录

sudo cp ./scripts/goproxy.service /usr/lib/systemd/system/

启用守护进程

sudo systemctl enable goproxy
sudo systemctl start goproxy

持续集成(可选)

目的

开发者将代码提交到版本管理系统,之后的编译构建,自动化测试,打包,发布,部署等都是固定流程,应该由持续集成系统去完成。

使用持续集成,可以降低重复繁琐操作的出错率。

选型

有许多在线的持续集成服务,由于我们是私网部署,我们选择了 Jenkins ,它是由 Java 语言编写的开源 CI&CD 服务,搭建十分便捷 。

部署

详见 官方搭建指南 ,以下仅作记录。

安装 Java 1.8 运行环境

sudo yum -y install java-1.8.0-openjdk-devel

启用 Jenkins 存储库

curl --silent --location http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo | sudo tee /etc/yum.repos.d/jenkins.repo
sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key

安装 Jenkins

sudo yum -y install jenkins

启用守护程序

sudo systemctl start jenkins
sudo systemctl enable jenkins

按照提示进行配置

浏览器访问当前主机的 8080 端口,开始配置。

安装建议的插件,按需求以后添加插件。

反向代理

这里我们选用使用最广泛的 NGINX 作为反向代理服务。

鉴于篇幅,仅介绍对于 Gogs 的反向代理。

安装 NGINX

sudo yum install -y nginx

HTTPS 证书

获取证书的途径有很多,可以购买商业证书,或者申请免费证书,私网环境为了简单,我就选择自签证书。

使用 openssl 自签证书可以 参考这篇

也可以用 Gogs 可执行程序提供的子命令:

./gogs cert -ca=true -duration=8760h0m0s -host=go.findshank.com

会在执行目录下得到两个文件: cert.pemkey.pem

Gogs 配置

找到 Gogs 的配置文件 gogs/custom/conf/app.ini ,确保 ROOT_URL 为 https 协议,比如: https://go.findshank.com 。其他的配置都不用改。

NGINX 配置

先把 /etc/nginx/nginx.conf 中的默认 server 配置删除,你也可以把它注释掉,如下所示:

    #server {
    #    listen       80 default_server;
    #    listen       [::]:80 default_server;
    #    server_name  _;
    #    root         /usr/share/nginx/html;

    #    # Load configuration files for the default server block.
    #    include /etc/nginx/default.d/*.conf;

    #    location / {
    #    }

    #    error_page 404 /404.html;
    #        location = /40x.html {
    #    }

    #    error_page 500 502 503 504 /50x.html;
    #        location = /50x.html {
    #    }
    #}

新建配置文件 /etc/nginx/conf.d/default.conf,填入如下内容:

server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name go.findshank.com;
        ssl_certificate "/home/shank/gogs/keys/cert.pem";
        ssl_certificate_key "/home/shank/gogs/keys/key.pem";        

        location / {
                proxy_set_header X-Real-IP $remote_addr;      
                proxy_pass http://127.0.0.1:3000$request_uri; 
        }
}

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name go.findshank.com;
        return 301 https://$host$request_uri;
}

验证配置

nginx -t

启用守护程序

sudo systemctl start nginx
sudo systemctl enable nginx

可能遇到的问题

参考