昨晚访问 USTC 的 Rust Crates 反代源一直不太顺畅,于是有了自己搭建的想法。早上上课摸鱼弄了出来。搭建方案写篇博客,看到网上相关的教程还挺少的...
目前在自己的站点上已经提供公共反向代理 http://crates.io 的服务,欢迎使用:
反代 http://crates.io:https://crates.delbertbeta.cc/
Cargo registry:https://crates.delbertbeta.cc/crates.io-index (2h 同步一次)
使用方法
使用文本编辑器打开下面这个文件,如果没有则自行创建。
// Linux & Mac:
~/.cargo/config
// Windows:
C:Users${your-username}.cargoconfig
编辑文本内容如下:
[source.crates-io]
replace-with = 'delbertbeta'
[source.delbertbeta]
registry = "https://crates.delbertbeta.cc/crates.io-index"
重新在项目中运行 cargo build
即可从新的源更新 index。
反向代理 http://crates.io
因为 http://crates.io 不是一个单纯静态文件分发站点,不同于 Linux 软件源那样使用 rsync 之类的工具同步所有的文件到服务器上,保持同步文件结构,单纯的静态分发就可以了,http://crates.io 是依靠 api 对外服务的,例如:https://crates.delbertbeta.cc/api/v1/crates,crates.io 项目中没有给出手动部署的方案,官方推荐使用 Heroku 一键部署,但是部署到国外的云平台上,带宽速度可连接性和 S3 一样又不能得到保障。明显此时直接反向代理 crates.io 是省时省力又节约自己服务器流量和硬盘的好办法,这里给出 nginx 反向代理 crates.io 的方案。
首先在 /etc/nginx/sites-enabled
下复制或创建一个虚拟站点配置文件。
其核心部分如下:
location / {
proxy_buffering on;
proxy_connect_timeout 10s;
proxy_cache STATIC;
proxy_cache_valid 200 12h;
proxy_cache_valid 400 502 504 1m;
proxy_cache_valid any 5m;
proxy_cache_revalidate on;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_set_header Host crates.io;
proxy_ssl_server_name on;
proxy_pass https://crates.io;
}
这里我们用到了 nginx 的 cache feature,用硬盘空间换降低流量开销和提高速度,还需要配置一下 cache。
# File: /etc/nginx/nginx.conf
http {
...
proxy_cache_path ${path-to-your-cache-folder} keys_zone=STATIC:100m levels=1:2 inactive=6h max_size=1g;
...
}
注意将 ${path-to-your-cache-folder}
替换成你的缓存要存放的目录。
配置完成之后保存,systemctl restart nginx
,在浏览器里面访问这个站点就可以看到代理成功的 crates.io 了。
搭建 crates.io-index
有了反代的 http://crates.io,可是 cargo 并不会去从我们的站点去下载 crate,所以还需要自己搭建一个 crates.io-index service。
http://crates.io 是把自己所有的包的索引放在 Github 上的,其实我们平时用的 Cargo 的时候它自动去拉取索引其实就是在本地克隆一份这个仓库:https://github.com/rust-lang/crates.io-index/。
我们在服务器上也拉取一份这个仓库
git clone https://github.com/rust-lang/crates.io-index.git
cd crates.io-index
这个仓库下有一个 config.json
,打开编辑,嘿嘿嘿,很明白你要做什么了吧。
# File: crates.io-index/config.json
{
"dl": "https://crates.delbertbeta.cc/api/v1/crates",
"api": "https://crates.delbertbeta.cc"
}
然后 git add . && git commit
素质二连。
这时候,为了方便好用,我们选择部署一个 Git over HTTP 服务来将这个仓库暴露出去,作为 Cargo 的 source registry。
这里直接使用 git-core 自带的 git-http-backend 配合 fcgiwrap 来构建一个 cgi,提供 Git over HTTP 服务。
apt install fcgiwrap
systemctl start fcgiwrap
修改站点配置文件
location ~ /crates.io-index/(.*) {
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
# export all repositories under GIT_PROJECT_ROOT
fastcgi_param GIT_HTTP_EXPORT_ALL "";
fastcgi_param GIT_PROJECT_ROOT ${parent-folder-of-your-repo};
fastcgi_param PATH_INFO /crates.io-index/$1;
fastcgi_param REMOTE_USER $remote_user;
}
注意将上面的 ${parent-folder-of-your-repo}
替换成你的 crates.io-index
仓库的父文件夹的路径。
然后重启 nginx 即可。
配置 SSL (可选)
我这里直接用 LetsEncrypt
sudo apt-get install certbot python-certbot-nginx -t stretch-backports
certbot
选择你的域名,全自动配置。
定时同步
建立 crates.io-index.sh
#!/bin/sh
cd ${path-of-crates-io-index}
git fetch
git merge origin/master --no-edit
git prune
exit 0
使用 cron 定时任务定时执行以上脚本,执行 crontab -e
。
# 每两小时同步一次
0 */2 * * * sh ${path-to-the-file}/crates.io-index.sh
完成
可以按照文章最开始的配置方法,将自己本机的 Cargo 配置成自己搭建的 Crates 源了。快乐~