对于国内开发者而言,GitHub访问问题一直是个痛点。网络延迟高、连接不稳定、偶尔无法访问等问题,严重影响开发效率。特别是在需要频繁拉取代码、提交变更或查阅文档时,这些问题尤为突出。
自建GitHub镜像站能有效解决这些问题。通过在国内服务器上建立GitHub的镜像,开发者可以:
目前主流的镜像站搭建方案有三种,各有特点:
这是最简单的入门方案,适合个人开发者。原理是利用Gitee提供的仓库导入功能,将GitHub仓库同步到Gitee平台。优势是:
但缺点也很明显:
这是功能最完整的方案,适合中小团队。通过在自有服务器上部署Nginx反向代理,实现:
技术实现上主要依赖:
这个方案的优点是功能完整,缺点是:
这是Kubernetes社区推荐的方案,专为大规模CI/CD场景优化。核心功能包括:
适合:
部署方式以Docker为主,需要一定的Kubernetes知识。
对于个人开发者,我推荐先从Gitee方案入手。具体操作:
准备GitHub仓库
Gitee仓库创建
等待同步完成
注意:Gitee对单个仓库有1GB的大小限制,超过此限制的仓库需要特殊处理。
手动同步效率低,我们可以用Webhook+脚本实现自动同步。以下是经过生产验证的脚本:
bash复制#!/bin/bash
# 配置项
GITEE_REPO="git@gitee.com:username/repo.git"
GITHUB_REPO="git@github.com:username/repo.git"
WORK_DIR="/tmp/sync_$(date +%s)"
LOG_FILE="/var/log/github_sync.log"
# 创建临时目录
mkdir -p $WORK_DIR
cd $WORK_DIR || exit 1
# 记录开始时间
echo "[$(date)] 开始同步仓库" >> $LOG_FILE
# 克隆Gitee仓库
git clone --mirror $GITEE_REPO . >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
echo "克隆Gitee仓库失败" >> $LOG_FILE
exit 1
fi
# 添加GitHub远程
git remote add github $GITHUB_REPO >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
git remote set-url github $GITHUB_REPO >> $LOG_FILE 2>&1
fi
# 执行同步
git fetch github --prune >> $LOG_FILE 2>&1
git push --mirror origin >> $LOG_FILE 2>&1
# 清理
cd ..
rm -rf $WORK_DIR
# 记录完成时间
echo "[$(date)] 同步完成" >> $LOG_FILE
配置GitHub Webhook的要点:
问题1:同步时出现"Permission denied"
ssh -T git@gitee.com问题2:大仓库同步超时
git clone --depth 1问题3:Webhook不触发
curl -X POST your-webhook-url推荐使用腾讯云或阿里云的轻量应用服务器,配置建议:
基础软件安装:
bash复制# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装必要软件
sudo apt install -y nginx git certbot python3-certbot-nginx
# 配置防火墙
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
镜像仓库的维护是关键,推荐以下目录结构:
code复制/data
├── github-mirror
│ ├── repo1.git
│ ├── repo2.git
│ └── ...
└── scripts
├── sync.sh
└── cleanup.sh
同步脚本示例:
bash复制#!/bin/bash
MIRROR_DIR="/data/github-mirror"
LOG_FILE="/var/log/github_mirror.log"
# 定义要镜像的仓库列表
REPOS=(
"https://github.com/vuejs/vue.git"
"https://github.com/tensorflow/tensorflow.git"
)
# 创建目录
mkdir -p $MIRROR_DIR
cd $MIRROR_DIR || exit 1
echo "$(date) 开始同步" >> $LOG_FILE
for repo in "${REPOS[@]}"; do
repo_name=$(basename $repo .git)
if [ -d "$repo_name.git" ]; then
cd "$repo_name.git" || continue
echo "更新仓库: $repo_name" >> $LOG_FILE
git remote update >> $LOG_FILE 2>&1
git remote prune origin >> $LOG_FILE 2>&1
cd ..
else
echo "克隆新仓库: $repo_name" >> $LOG_FILE
git clone --mirror $repo "$repo_name.git" >> $LOG_FILE 2>&1
fi
done
echo "$(date) 同步完成" >> $LOG_FILE
设置定时任务(每天凌晨3点执行):
bash复制0 3 * * * /data/scripts/sync.sh
完整的Nginx配置需要考虑以下方面:
nginx复制server {
listen 443 ssl;
server_name mirror.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/mirror.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mirror.yourdomain.com/privkey.pem;
location / {
proxy_pass https://github.com;
proxy_set_header Host github.com;
proxy_set_header X-Real-IP $remote_addr;
# 缓存配置
proxy_cache github_cache;
proxy_cache_valid 200 302 60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
}
}
nginx复制location ~ ^/.*\.git/ {
proxy_pass https://github.com;
proxy_set_header Host github.com;
# 禁用缓冲,提高实时性
proxy_buffering off;
proxy_request_buffering off;
# 大文件支持
client_max_body_size 0;
}
nginx复制proxy_cache_path /var/cache/nginx/github levels=1:2 keys_zone=github_cache:10m inactive=24h max_size=10g;
建议部署Prometheus监控:
yaml复制# prometheus.yml
scrape_configs:
- job_name: 'nginx'
static_configs:
- targets: ['localhost:9113']
metrics_path: /metrics
关键监控指标:
rate(nginx_http_requests_total[1m])sum(rate(nginx_cache_hits{zone="github_cache"}[1m])) / sum(rate(nginx_cache_misses{zone="github_cache"}[1m]))rate(nginx_http_request_size_bytes[1m])推荐使用Docker Compose部署:
yaml复制version: '3.8'
services:
ghproxy:
image: gcr.io/k8s-prow/ghproxy:v20230718-1e70f04c3a
ports:
- "8080:8080"
volumes:
- ./cache:/cache
environment:
- CACHE_SIZE_GB=20
- THROTTLING_TIME_MS=800
restart: unless-stopped
关键参数说明:
CACHE_SIZE_GB:缓存大小,建议设置为可用磁盘空间的70%THROTTLING_TIME_MS:限流阈值,根据GitHub API限制调整在CI/CD系统中配置:
yaml复制# GitHub Actions示例
env:
GITHUB_API_URL: http://your-ghproxy:8080
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
在命令行中使用:
bash复制export GITHUB_API_URL=http://your-ghproxy:8080
export GITHUB_TOKEN=your_token
yaml复制command:
- --merge-threshold=5
- --merge-window=500ms
yaml复制ports:
- "9090:9090" # Prometheus监控端口
yaml复制environment:
- ALLOWED_ORIGINS=your-ci-system.com
根据实际使用情况调整缓存策略:
| 资源类型 | 缓存时间 | 建议配置 |
|---|---|---|
| 代码仓库 | 6小时 | proxy_cache_valid 200 302 6h |
| API响应 | 5分钟 | proxy_cache_valid 200 302 5m |
| 静态资源 | 24小时 | expires 1d |
| 动态内容 | 1分钟 | proxy_cache_valid 200 302 1m |
nginx复制location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
# 其他配置...
}
nginx复制limit_req_zone $binary_remote_addr zone=github:10m rate=10r/s;
location / {
limit_req zone=github burst=20;
# 其他配置...
}
nginx复制log_format github '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/github-access.log github;
问题1:Nginx返回502错误
curl -v https://github.comtail -f /var/log/nginx/error.lognginx复制proxy_connect_timeout 60s;
proxy_read_timeout 300s;
问题2:缓存不更新
rm -rf /var/cache/nginx/*nginx复制proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
问题3:SSL证书过期
certbot renew --force-renewalcrontab -lopenssl x509 -enddate -noout -in /path/to/cert.pem| 维度 | Gitee方案 | Nginx代理 | ghProxy |
|---|---|---|---|
| 延迟 | 50-100ms | 100-200ms | 150-300ms |
| 吞吐量 | 中等 | 高 | 极高 |
| 功能完整性 | 60% | 90% | 70% |
| 维护复杂度 | 低 | 中 | 高 |
| 成本 | 免费 | $5-20/月 | $50+/月 |
个人开发者
中小团队
大型企业
对于有特殊需求的团队,可以考虑混合部署:
配置示例:
nginx复制location /api/ {
proxy_pass http://ghproxy:8080;
}
location / {
proxy_pass https://github.com;
}
对于跨国团队,可以在多个区域部署镜像站:
基于用户位置自动选择最优节点:
nginx复制geo $nearest_mirror {
default mirror-us;
192.168.1.0/24 mirror-cn;
}
server {
location / {
proxy_pass http://$nearest_mirror;
}
}
使用Kubernetes管理镜像站集群:
yaml复制apiVersion: apps/v1
kind: Deployment
metadata:
name: github-mirror
spec:
replicas: 3
selector:
matchLabels:
app: mirror
template:
spec:
containers:
- name: nginx
image: nginx:1.25
volumeMounts:
- mountPath: /var/cache/nginx
name: cache
volumes:
- name: cache
emptyDir: {}
nginx复制proxy_cache_path s3://your-bucket/cache levels=1:2 keys_zone=s3_cache:10m;
nginx复制gzip on;
gzip_types text/plain application/json;
bash复制# 每周同步趋势仓库
curl -s https://github.com/trending | grep h3 | awk -F'/' '{print $2,$3}' | while read user repo; do
git clone --mirror "https://github.com/$user/${repo%.*}.git"
done
在实际部署中,我发现镜像站的性能瓶颈往往不在服务器配置,而在于网络质量和缓存策略。经过多次调优,总结出几个关键点:
对于企业用户,建议先从Nginx方案入手,待规模扩大后再考虑ghProxy。个人开发者用Gitee方案就能获得很好的体验。无论选择哪种方案,定期维护和监控都是必不可少的。