go proxy结合nginx解决golang项目公私有模块依赖问题

go从1.11开始引入了go module,其中有一个go proxy的特性能帮我们解决第三方模块的下载,比如 golang.org/x 下的模块。同时公司也有自己的私有模块要依赖。这里是一步解决同时下载公私有模块的问题。

(注意: goproxy终极解决方法看这里,这里适用go1.11、1.12)

1.公用的go proxy

常用的go proxy

export GOPROXY=https://goproxy.io

export GOPROXY=https://athens.azurefd.net

# 国内的
export GOPROXY=https://goproxy.cn

go get 会去请求go proxy,go proxy有的话就返回来,没有就去github、golang.org等vcs去下载,再缓存起来

2.自己的go proxy

一般公司都有自己的gitlab、gogs之类的托管平台,上面的公用的go proxy下载不了公司内部的依赖,一个简单的方法就是找一台能上谷歌的内网机器做 go proxy,这样既能下外网的依赖,也能下内网的依赖。这里假设git.test.com是我公司git服务器的域名。我们可以用这个微软开源的athens

简单部署

base=/home/chen/athens
data_dir=$base/data
user_dir=$base/root
name=athens-proxy

# athens默认是3000端口
# 网络模式用了host模式,以便访问内网的机器和域名

docker run -d \
  --name ${name} \
  -v ${data_dir}:/var/lib/athens \
  -v ${user_dir}:/root \
  -e ATHENS_DISK_STORAGE_ROOT=/var/lib/athens \
  -e ATHENS_STORAGE_TYPE=disk \
  --net host \
  --restart always \
  gomods/athens:v0.5.0

# 假设内部域名是git.test.com,可以在主机的/etc/hosts里面加进去
# go get默认走https协议,如果你的gitlab或者gogs只有http或者ssh两种访问方式,用ssh替代https

docker exec ${name} git config --global url."git@git.test.com:".insteadOf "https://git.test.com"

# 记得进入容器里面用 ssh-keygen -t rsa 命令生成秘钥,把公钥上传到git服务器
# 公钥存在容器的/root/.ssh/下

# athens也可以用默认的网络模式,不过明显慢了很多
docker run -d \
  --name ${name} \
  -v ${data_dir}:/var/lib/athens \
  -v ${user_dir}:/root \
  -e ATHENS_DISK_STORAGE_ROOT=/var/lib/athens \
  -e ATHENS_STORAGE_TYPE=disk \
  --add-host=git.test.com:192.168.40.131 \
  --restart always \
  gomods/athens:v0.5.0

开启go proxy

# 假设athens所在的ip是192.168.1.100
export GO111MODULE=on
export GOPROXY=http://192.168.1.100:3000

在你的go代码里面

# 依赖的go module是 git.test.com/web/server.git ,在go.mod能看到
import "git.test.com/web/server.git/pkg/utils"

3.不用翻的go proxy

nginx是个好东西,利用它的路由匹配规则,转发到不同的go proxy处理,这样就不用翻了
这里nginx机器是192.168.40.131
(注意利用nginx的缓存,这里没写)

# athens.conf
# 把该文件放到/etc/nginx/conf.d/下并执行重启 nginx -s reload

server {
    listen 4000;
    
    # 外部的依赖转发到外面的go proxy
    location / {
        proxy_pass https://goproxy.cn;
    }
    # 内部依赖的go proxy,也就是上面启动的athens
    # github的依赖也可以走本地的go proxy,可以做缓存
    location ~ /(git\.test\.com|github\.com)/ {
        proxy_pass http://192.168.1.100:3000;
    }
}

然后

export GOPROXY=http://192.168.40.131:4000

4.解决go get包必须带 .git 后缀的问题

看上面我们知道每次下载都要加上.git后缀

go get git.test.com/web/server.git@v0.0.1

代码里面

import "git.test.com/web/server.git/pkg/utils"

有没有办法去掉路径里面的 .git 呢,当然有啦。首先你的gitlab或者gitea等先开启https,自己做CA,CA签发证书给服务器用,准确来说给git服务器的nginx用,然后客户端pc导入CA的根证书

先把https里面的概念理清楚,再去做,理解了才能灵活运用

关于证书生成:
Centos(重点看): 基于OpenSSL自建CA和颁发SSL证书
Ubuntu: Ubuntu使用OpenSSL生成数字证书详解

ubuntu导入ca根证书注意:

# 假设ca的根证书是cacert.pem,重命名成crt结尾的
cp cacert.pem cacert.crt
mv cacert.crt /usr/local/share/ca-certificates/
update-ca-certificates

curl -v https://git.test.com  #测试

# 如何不成功试试这个格式转换的,再重新导入
openssl x509 -outform der -in cacert.pem -out cacert.crt

看完上面的文章你应该能生成用于gitlab或者gitea的签发证书和私钥了吧
注意: 签发证书时 Common Name 最好填授予证书的服务器域名或主机名,这里是 git.test.com,其他情况你也可以试试

不管是gitlab还是gitea,如何利用nginx解决路径带.git的问题,看 这篇文章

gitlab开启https我就不说了,解决路径带 .git的问题上面说了

例子
下面说说我用的gitea(gogs的社区版):
gitea安装
gitlab有配套的nginx组件,gitea没有,那就自己做一个反向代理好了,直接上nginx的配置

# gitea的默认端口好巧也是3000,自己可以改配置,我改成3333
upstream gitea {
    server 192.168.40.131:3333;
}

# nginx刚好跟gitea在同一台机器
server {
    listen 192.168.40.131:80;
    server_name git.test.com;   

    # 这里选择重定向到https去
    rewrite ^(.*)$ https://${server_name}$1 permanent; 
    
    # 也可以不重定向
    #location / {
    #	proxy_pass http://gitea;
    #}
}

server {
    listen    443;
    server_name  git.test.com;
    
    ssl on;
    ssl_session_cache        shared:SSL:10m;
    ssl_session_timeout      20m;
    ssl_session_tickets       on;
    ssl_certificate /data/gitea/ssl/server.crt;      # 自己ca签发的
    ssl_certificate_key /data/gitea/ssl/server.key;  # 自己的私钥
    
    location / {
        proxy_cache off; 
        proxy_pass http://gitea;
    }
    location ~* ^/[^/]+/[^/]+$ {
        if ($http_user_agent ~* '^go.*') {
            return 200 "<!DOCTYPE html><head><meta content='$host$uri git ssh://git@$host:$uri.git' name='go-import'></head></html>";
        }
        proxy_cache off;
        proxy_pass http://gitea;
    }
    location ~* ^/(?<holder>[^/]+)/(?<project>[^/]+)/.*$ {
        set $goRedirect 'https://$host/$holder/$project?$args';
        if ($http_user_agent ~* '^go.*') {
            return 301 $goRedirect;
        }
        proxy_cache off;
        proxy_pass http://gitea;
    }
}

athens也要做改变了,它要导入我们自己制作的CA根证书

base=/home/chen/athens
data_dir=$base/data
user_dir=$base/root
cert_dir=$base/ca   #这里存放ca的根证书,它是cacert.pem重命名为cacert.crt的,参考Ubuntu是如何导入ca证书的
name=athens-proxy

docker run -d \
  --name ${name} \
  -v ${data_dir}:/var/lib/athens \
  -v ${user_dir}:/root \
  -v ${cert_dir}:/usr/local/share/ca-certificates \
  -e ATHENS_DISK_STORAGE_ROOT=/var/lib/athens \
  -e ATHENS_STORAGE_TYPE=disk \
  --restart always \
  --net host \
  gomods/athens:v0.5.0
  
docker exec ${name} sh -c 'update-ca-certificates'

# 记得进入容器里面用 ssh-keygen -t rsa 命令生成秘钥,把公钥上传到git服务器
# 公钥存在容器的/root/.ssh/下

go代码里面

# 路径里面没有.git了,这次舒服了吧
import "git.test.com/web/server/pkg/utils"

总结,go get–>nginx–>go proxy–>nginx–>gitea,一路走下来不容易啊

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值