Asteroid B612

纯内网部署goproxy和pkgsite

记录下纯内网部署的流程,以备后续忘了(老了,记忆力差)。
在一个没有DMZ,无法通过代理获取外部信息的纯内网中开发是比较烦心的事情(当然也没那么纯,数据还是可以通过U盘拷进去,但是在网络上是纯纯的!),内网只有maven、npm和Pypi仓,没有go的goproxy,所以需要自行为团队搭建一个(其实之前是白嫖别的团队的,别人的倒闭跑路了=-=)。

搭建Goproxy - Athens

offline模式优化

GOPROXY选择Athens,这是一个很方便使用的Go模块数据存储和代理,提供了offline模式。

但是,athens在offline模式下,因为无法连接外部模块的版本控制系统,所以不支持访问/模块/@latest端点。而对于pkgsite这个系统来说,又是需要访问/@latest的,所以我们需要修改Athens的源码,让他支持在offline模式下,提供/@latest服务。

修改的思路是,如果是离线模式,那么就从缓存中找到更新时间最新的模块版本,作为latest版本展示,这一部分的代码在pkg/download/protocol.go中,修改的commit见
https://github.com/Starainrt/athens/commit/b6207330cf75ebfde838bfb7e9100b82ab85c96a

修改完成后,再执行docker build -t gomods/athens:latest构建新镜像即可。
如果镜像已经部署到内网,重新拷贝docker image进内网过大(好像是50多Mb),也可以这样做:

  1. 在外部直接编译二进制文件
  2. 用upx压缩后,大小只有10Mb,(或者zip压缩下,传入zip文件再解压)之后将二进制传入内网
  3. 使用docker copy命令将新编译的athens拷入到运行的容器中
  4. 使用docker exec进入到容器中,将拷入进来的新的athens替换容器内部的/bin/athens-proxy,并赋予执行权限。
  5. 执行docker commit athens生成经镜像,再使用docker tag重新打tag即可。

部署Athens

接着,正式开始部署Athens,模块同步思路很简单:
首先,在外网环境,先部署一个Athens,同步缓存后,将挂载的文件夹全部拷贝到内网,内网的Athens挂载相同的目录即可

  1. 外网部署Athens,这里使用https://goproxy.cn加速下载,使用https://sum.golang.google.cn/加速验证

    docer run -d -v 模块储存地址:/var/lib/athens -e ATHENS_DISK_STORAGE_ROOT=/var/lib/athens -e ATHENS_STORAGE_TYPE=disk -e ATHENS_SUM_DBS=https://sum.golang.google.cn/ -e ATHENS_GO_BINARY_ENV_VARS=GOPROXY=https://goproxy.cn,direct -p 3000:3000 --name athens --restart always gomods/athens:latest
  2. 储存Package时,如果需要完整储存package及其依赖链,设置GOPROXY为http://服务地址:3000,再用go get 模块名go mod download 模块名触发模块储存。
    举例:

    go env -w GOPROXY=http://服务地址:3000
    go mod download github.com/google/gopacket@latest
  3. 如果只需要储存单个package,或者自行解析go.mod,可以直接HEAD请求http://Athens地址/模块路径/@v/版本号.zip来触发Athens储存。
  4. 接着,将储存文件夹拷入U盘中,windows上可以使用fastcopy增量拷贝(⚠️注意商用授权),也可以使用rsync增量拷贝
  5. 在内网中,用同样的方法将U盘中的文件夹拷入到docker挂载文件夹中。
  6. 在内网中,启动Athens,指定offline模式即可:

    docker run -d -v 内网模块储存地址:/var/lib/athens  -e ATHENS_DISK_STORAGE_ROOT=/var/lib/athens  -e ATHENS_STORAGE_TYPE=disk -e ATHENS_NETWORK_MODE=offline -e ATHENS_GONOSUM_PATTERNS=\* --name athens --restart always  -p 3000:3000  gomods/athens:latest
  7. 最后内网使用时,除了设置GOPROXY,记得设置go env -w GOSUMDB=off

搭建pkgsite,提供文档服务

pkgsite的镜像地址是:https://github.com/golang/pkgsite,我们要搭建的是一整套前端和后端

其他环境准备

  1. 需要一个PostgreSQL数据库,以pg16为例,外网环境执行

    docker pull postgres:16-alpine
    docker save postgres:16-alpine -o ./pg16.tar
    #下面的步骤可以省略
    gzip ./pg16.tar

    然后将./pg16.tar./pg16.tar.gz拷贝到U盘中

  2. 需要migrate工具,前往https://github.com/golang-migrate/migrate/releases/按照服务器架构下载tar.gz压缩文件,保存到U盘中

预编译pkgsite

  1. 在外网环境,下载pkgsite源码,并进行预编译

    git clone --depth=1 https://github.com/golang/pkgsite
    cd pkgsite
    # windows powershell下使用 $env:CGO_ENABLED=0
    export CGO_ENABLED=0
    #worker进程默认监听localhost:8080,如果8080已有服务运行,修改./cmd/worker/main.go中监听的端口号,或者自行添加一个flag
    go build -ldflags "-w -s" -o worker ./cmd/worker/main.go
    go build -ldflags "-w -s" -o frontend ./cmd/frontend/main.go
    go build -ldflags "-w -s" -o db ./devtools/cmd/db/main.go
  2. 编译完成后,pkgsite文件夹中得到三个文件worker,frontend,db,将pkgsite整个文件夹拷贝到u盘中。
  3. 检查U盘,应当有如下三个文件(文件夹)
    (1) pkgsite文件夹
    (2) Pg镜像
    (3) Migrate工具,如migrate.linux-amd64.tar.gz

创建pg数据库

  1. 内网执行docker load -i ./pg16.tar.gz加载pg镜像,docker images查看镜像,如果tag没有附上,则执行docker tag <hashid> postgres:16-alpine命令
  2. 启动镜像docker run -d -v 保存pg数据的文件夹:/var/lib/postgresql/data -e POSTGRES_PASSWORD=数据库密码 -p 127.0.0.1:5432:5432 postgres:16-alpine

配置migrate工具

  1. 在服务器上,解压migrate工具,如:tar -zxvf migrate.linux-amd64.tar.gz
  2. 解压会得到一个migrate二进制,将migrate直接服务器PATH变量中记录的任意一个路径下,如mv ./migrate /bin

初始化数据

  1. 将U盘中pkgsite文件夹移动到服务器上
  2. 进入pkgsite文件夹,执行命令赋权chmod +x ./devtools/*.sh
  3. 设置如下环境变量

    export GO_DISCOVERY_DATABASE_PASSWORD=pg数据库的密码
    export GO_MODULE_PROXY_URL=你的Athens地址
  4. 执行如下命令初始化数据库

    ./db create
    ./devtools/migrate_db.sh up

    如果系统太老,提示env: invalid Option -- 'S',则删掉./devtools/migrate_db.sh第一行的#!/usr/bin/env -S bash -e重新执行

启动

  1. 此时,可以启动pkgsite前后端了

    #启动后端
    ./worker -bypass_license_check
    #启动前端,绑定8080端口
    ./frontend -bypass_license_check -host 0.0.0.0:8080
  2. 访问 http://服务器ip:8080 即可看到前端界面
  3. 请求 http://后端地址/@v/版本号,即可添加数据,比如http://后端地址/github.com/gomods/athens/@v/latest

其他

设置反代后,可以通过一些手段实现用户访问Athens时,自动更新pkgsite数据:

  1. 我自己写个反代,内部处理实现
  2. nginx配合lua模块实现
  3. caddy配合插件实现
  4. 定期解析访问日志,异步更新

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »