海外云服务器搭建 Harbor 私有容器镜像仓库完整教程(2026最新版)
Meta Description: 海外云服务器搭建 Harbor 私有容器镜像仓库完整教程:Docker Compose 一键部署 CNCF 毕业项目 Harbor v2.15,覆盖 harbor.yml 配置详解、Let's Encrypt HTTPS 证书、Trivy 镜像漏洞扫描、项目级 RBAC 权限、跨仓库镜像复制、垃圾回收(GC)避坑、Nginx 反代与安全加固、备份升级,另含 Harbor 与 Docker Hub / GitLab Registry / Nexus 的选型对比、服务器配置推荐表、服务商价格参考表,以及 9 条常见问题 FAQ。
> 关键词:Harbor 搭建教程、私有镜像仓库、Docker Registry、Harbor 部署、海外云服务器 Harbor、Trivy 漏洞扫描、容器镜像仓库、Harbor garbage collection、Harbor RBAC 权限、self-hosted registry
前言:你的镜像,不该存在别人的账号里
一句话答案:Harbor 是 CNCF(云原生计算基金会)托管的开源企业级容器镜像仓库,用一台海外云服务器加一套 Docker Compose 就能搭起来;它默认监听 80/443 端口,自带 Web 管理界面、项目级 RBAC 权限、Trivy 漏洞扫描、跨仓库镜像复制和垃圾回收,能把原本放在 Docker Hub 上的私有镜像搬回自己的机器,从此不再受别人的限速、账号封禁和网络可达性摆布。
如果你已经按本站的教程搭好了 Docker + Portainer、跑起了容器,那你迟早会撞上同一个问题:镜像存哪儿? 大多数人的默认答案是 Docker Hub。它免费、开箱即用,但只要你真的拿它跑生产,就会接连遇到下面这几件事:
- 匿名拉取限速。Docker Hub 对匿名账号的镜像拉取有速率限制,CI 流水线一并发构建,第二个任务就开始报 toomanyrequests: You have reached your pull rate limit。
- 私有仓库收费。免费账号只给 1 个私有仓库,团队稍微一多就得升级付费档;镜像又大又占额度。
- 账号连坐风险。一个账号被封或欠费,所有依赖它拉镜像的服务器会在下一次滚动重启时全部拉不到镜像——你的集群不是被自己弄挂的,是被别人的风控弄挂的。
- 网络不可达。在国内节点上直连 Docker Hub 经常超时,构建一次要重试好几次;跨境拉镜像的带宽成本也实打实。
- 合规与审计。企业镜像里可能带着内部代码和环境变量,放到第三方仓库,等于把软件的依赖树交给别人管。
私有镜像仓库解决的正是这几个问题。 而 Harbor 是这个赛道里最"企业级"的开源选择:它不只是 Docker 官方 registry 那一个裸的存储后端,而是在其上加了用户管理、权限控制、漏洞扫描、镜像复制、操作审计这些生产环境真正需要的能力——这也是它为什么能成为 CNCF 的毕业(Graduated)项目。
本文给出可直接复制执行的完整命令,以 Ubuntu 22.04 + Docker 为主线(Debian 12 同样适用),覆盖:买服务器 → 装 Docker 与 Compose → 下载并校验 Harbor 安装包 → 写 harbor.yml → 配置 HTTPS 证书 → 一键安装(含 Trivy)→ 推拉镜像 → 项目权限与镜像复制 → 垃圾回收(不配这一步磁盘会被删不掉的旧镜像撑爆) → 内置 Nginx 入口与安全加固 → 备份升级,最后附服务器配置推荐表、服务商价格参考表,以及 9 条常见问题。
> 🚀 还没有海外云服务器?通过 5.chengzicloud.cloud 选购阿里云 / AWS / 腾讯云国际版,享专属折扣和中文技术支持。
一、先分清边界:Harbor 和你可能已经装过的东西各管什么
在动手前先做一次选型。镜像仓库的选型错误不是"多花点钱",而是整篇文章的命令都不适用——因为它们解决的根本不是同一层问题。本站的容器与 DevOps 家族已经有若干篇专文,读者最容易困惑的就是"这些我是不是要重复装",下面这张边界表一次说清,本文只负责 Harbor 这一层。
| 既有 / 相邻方案 | 它解决的问题 | 与本文的关系 |
|---|---|---|
| Docker + Portainer(本站已有专文) | "怎么跑容器、怎么看单机容器" | 它管的是容器的运行时与单机编排。本文管的是镜像本身存在哪。你可以用 Portainer 拉本文推上去的镜像 |
| GitLab CE + CI/CD(本站已有专文) | "代码托管 + 流水线 + 构建镜像" | 它内置了一个 Container Registry,但那是给 CI 用的附属能力;本文的 Harbor 是独立的企业级仓库(扫描、复制、配额、审计更完整),两者可并存,也可让 GitLab CI 构建后推到 Harbor |
| Kubernetes(本站已有专文) | "多机编排、调度、扩缩容" | K8s 的 kubelet 要从某个仓库拉镜像。私有镜像是 K8s 落地的前置条件,本文是它的镜像来源,不重复 K8s 本身的搭建 |
| Coolify(本站已有专文) | "自托管的 PaaS,从 Git 一键部署" | 它面向"应用部署",内部也会用到镜像仓库;与本文是上下游关系而非替代 |
| Gitea(本站已有专文) | "私有 Git 代码托管" | 代码在 Gitea,镜像在 Harbor——不少团队会把两者都装,形成"代码 + 制品"两个可信源 |
| MinIO(本站已有专文) | "S3 兼容的对象存储后端" | Harbor 的镜像层文件默认存本地盘,但可以把存储后端切到 S3/OSS/MinIO——两者是存储层与仓库层的关系 |
| Nginx 反代 + Let's Encrypt(本站已有专文) | "怎么给 Web 服务加域名和 HTTPS" | 本文第七节会用到它,但只讲 Harbor 特有的 HTTPS 配置,其余直接复用那篇,不重复 |
| Docker Hub / 阿里云 ACR / 腾讯云 TCR | "别人托管的镜像仓库,按量或按席位付费" | 开箱即用,但受限速、额度与网络;本文是它的自托管替代 |
| Harbor(本文) | "镜像存在哪、谁能推、有没有漏洞、怎么分发" | 只讲这一层 |
一张表判断你该装哪个:
| 你的情况 | 推荐方案 | |---|---| | 只用官方公共镜像,从不自建 | 不用装,Docker Hub 够用 | | 有几张自建私有镜像,个人开发 | Docker Hub 私有仓库(免费 1 个)或将就 | | 团队协作、需要权限和审计 | Harbor(本文) | | 已用 GitLab 做 CI/CD,团队 5 人以内 | 先用 GitLab 内置 Registry,够用再迁 Harbor | | 需要镜像扫描、跨地域分发、离线部署 | Harbor(本文) | | 完全不想运维、量也不大 | 云厂商托管仓库(ACR/TCR/ECR),按量付费 |
一个必须提前说清的能力边界:Harbor 是镜像与制品的仓库,它不负责构建镜像——构建是 CI(GitLab CI / Jenkins / GitHub Actions)或你本地 docker build 的事。把它当成"带保险箱和安检门的仓库"而不是"自动工厂",后面配起来就不会拧巴。同时,Harbor 的漏洞扫描依赖互联网下载漏洞库(Trivy DB),在纯内网/离线环境里需要额外做离线库的挂载,这一点文末 FAQ 会单独讲。
二、Harbor 到底是什么:它比裸 Registry 多了什么
先花两分钟把原理搞清楚,因为这决定了你后面怎么配、怎么不踩坑。
Harbor 的底座是 Docker 官方开源的 Distribution(也就是那个 registry:2 镜像)——它只做一件事:按 OCI 规范把镜像层文件存起来、需要时吐出去。它没有用户、没有权限、没有界面、没有扫描。Harbor 在它外面加了一圈企业级能力:
- Cloud native registry:同时支持容器镜像和 Helm Chart,作为容器运行时与编排平台的制品源。 - Role based access control(RBAC):以"项目(project)"为边界做权限隔离,同一个用户在不同项目里可以有不同的角色(访客 / 开发者 / 维护者 / 项目管理员)。 - Policy based replication(策略复制):按策略(仓库、标签、标签过滤)把镜像在多个 Harbor 实例之间同步,失败会自动重试——用来做负载均衡、跨地域分发、多云双活。 - Vulnerability Scanning(漏洞扫描):内置 Trivy 扫描引擎,定期扫描镜像里的 CVE,并可用策略阻止有高危漏洞的镜像被拉取部署。 - LDAP/AD / OIDC 集成:对接企业已有的目录服务或单点登录,不用再维护一套独立账号。 - Image deletion & garbage collection(GC):镜像删了空间不会自动释放,必须跑 GC 才能回收无人引用的 blob。 - Graphical user portal:网页界面,浏览、搜索、管理项目和用户。 - Auditing(审计):对所有仓库操作留日志——这是合规场景的硬需求。 - Proxy cache(代理缓存):可把 Harbor 配成某个上游仓库(如 Docker Hub)的拉取缓存,第一次拉从上游取、之后从本地秒回,既提速又降低对上游的依赖。 - RESTful API + Swagger:所有管理操作都能脚本化,方便和外部系统打通。
2.1 一个团队的典型拓扑
搭好之后,它的位置大概是这样:
`
开发者 / CI 构建机 ──docker push──▶ Harbor(海外云服务器)
│
Kubernetes / 生产服务器 ──docker pull──┘
│
(可选)策略复制 ──▶ 异地 Harbor 实例 / 云厂商托管仓库
`
一句话记住它的角色:它是团队镜像的"单一可信来源",所有推拉都经过它,因此权限、扫描、审计都只需在这一处做。
2.2 Harbor 与常见方案的对比
| 维度 | Docker 官方 registry:2 | Docker Hub(免费档) | GitLab 内置 Registry | Harbor(本文) | |---|---|---|---|---| | 用户与权限 | 无 | 有(账号级) | 有(项目级) | 项目级 RBAC + LDAP/OIDC | | Web 管理界面 | 无(需自建) | 有 | 随 GitLab | 完整界面 | | 镜像漏洞扫描 | 无 | 有限 | 需接第三方 | 内置 Trivy,可阻断拉取 | | 跨仓库复制 | 无 | 无 | 无 | 策略复制 + 失败重试 | | 垃圾回收 | 手动 | 不适用 | 有 | 图形化 + 可定时 | | 配额与代理缓存 | 无 | 付费解锁 | 部分 | 支持 | | 部署难度 | 极简 | 零 | 随 GitLab | 一套 Compose | | 适用场景 | 单机实验 | 个人/公共镜像 | 已用 GitLab 的团队 | 团队级私有仓库 |
结论:如果你只是单机实验,registry:2 一个容器就够;一旦涉及多人、多环境、要审计或要扫描,Harbor 是这一步该上的东西——而它的部署成本,其实也只是一套 Compose。
三、服务器配置推荐与价格参考
Harbor 官方给的资源要求很明确,别凭"一个仓库能有多重"的直觉去开机器:它内部是一组容器(nginx / core / portal / db / redis / registry / jobservice,加 Trivy 还有 scanner),每个都要占内存。
3.1 服务器配置推荐(按团队规模)
| 使用场景 | 推荐配置 | 为什么够用 | |---|---|---| | 个人 / 小团队试用 | 2核 4G + 40GB SSD | 官方最低要求就是 2 CPU / 4GB / 40GB,跑得起来但余量小 | | 3~10 人团队,正式使用(推荐) | 4核 8G + 160GB SSD | 官方推荐配置,留足扫描与并发拉取的余量 | | 镜像多、扫描频繁、并发拉取高 | 4核 8G 起 + 500GB SSD,或存储后端切对象存储 | 镜像层是磁盘杀手;高并发拉取建议开 Harbor 的 Redis 缓存层 | | 跨地域分发 / 高可用 | ≥2 台同配,配策略复制 | 单点 Harbor 挂了整个团队都拉不了镜像 |
> ⚠️ 两个硬约束:① 磁盘要 SSD,且容量别抠——每次推镜像都会多存一份层文件,删了不跑 GC 也不释放;② 不要和重业务抢同一台小机器,Harbor 的扫描和 GC 会瞬间吃满磁盘 IO。如果预算实在紧,宁可 2核4G 起步跑个人用,也别指望 1核1G——官方最低就是 4G 内存,低于它大概率装到一半就有容器反复重启。
3.2 服务商价格参考
下面按"2核4G / 4核8G"这两档实际会用的配置,整理公开官网参考区间:
| 服务商 | 2核4G 月付 | 4核8G 月付 | 数据中心 | 优点 | |---|---|---|---|---| | 阿里云国际版 ECS(通用型) | 约 $24~$36 | 约 $48~$72 | 新加坡/香港/硅谷 | 中文面板、支持支付宝、生态完整 | | AWS Lightsail | 约 $12~$20(4GB 档) | 约 $44~$84(8GB 档) | 全球 20+ 区域 | 固定月费、含流量额度、开箱即用 | | 腾讯云国际版 CVM(轻量/标准) | 约 $20~$30 | 约 $40~$60 | 香港/新加坡/东京 | 低延迟到国内、微信支付 | | Vultr | 约 $20~$24(4GB 档) | 约 $48~$96(8GB 档) | 全球 32 个 | 按小时计费、随时销毁重建 | | DigitalOcean | 约 $24(4GB 档) | 约 $48~$96(8GB 档) | 全球 14 个 | 文档完善、社区教程多 |
> 💡 镜像仓库的选址原则和监控机略有不同:它要靠近"拉镜像的人"——也就是你的 CI 构建机和生产服务器。团队在国内、业务在海外,就把 Harbor 放在香港/新加坡;跨地域团队多,就靠第二节的策略复制在每个地域放一个副本,不要让大家跨境拉几百 MB 的镜像。通过 5.chengzicloud.cloud 购买以上平台还可享额外折扣。
> 声明:本文价格数据采集于 2026 年 9 月,仅为公开官网参考区间。云服务器价格随区域、计费方式和活动浮动,请以各厂商官网实时价格为准。除特别标注外,金额单位均为美元(USD)。
四、部署实操:从空机器到能推镜像
以 Ubuntu 22.04 + Docker 为主线,CentOS 7 / Debian 12 差别只在包管理器,命令都标注了。全程命令可直接复制执行。
第 1 步:系统初始化与端口收敛
先确认机器版本和 glibc(这条对后面判断"要不要走原生安装"有用):
`bash
lsb_release -a
ldd --version | head -1
uname -m
`
🔴 CentOS 7 用户注意:CentOS 7 只有 glibc 2.17,很多现代软件的原生二进制跑不起来。但 Harbor 全程容器化,宿主机 glibc 不参与——所以它不会有 GLIBC_x.xx not found 的问题(本站第六个"全容器化项目"的同类结论,与 Immich / RustDesk / AdGuard Home / Umami / Loki 一致)。CentOS 7 上真正要手动补的是 Docker Compose v2 插件(见第 2 步)。
Harbor 只需要 80(HTTP)和 443(HTTPS) 两个端口。防火墙收敛到只放行它们和 SSH:
`bash
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
`
> ⚠️ 云安全组是防火墙之外的第二道门,且两道都要开。 最常见的"配置全对但就是访问不了",就是云平台层的安全组没放 443。阿里云 / 腾讯云 / AWS 都要在控制台的安全组里放行入方向 80、443。
> ⚠️ 端口冲突是新手第一大坑。 如果你的机器上已经装了 Nginx 并在监听 80/443,Harbor 自带的内置 Nginx 会起不来(报 bind: address already in use)。二选一:要么给 Harbor 换端口(http.port / https.port 改成 8080/8443),要么把宿主机 Nginx 停了、让 Harbor 独占 80/443。不建议两者都想占 443——正确的做法是让 Harbor 独占端口,或者反过来用外部 Nginx 反代并配 external_url。
第 2 步:安装 Docker Engine 与 Compose v2
Harbor 官方要求 Docker Engine > 20.10 且 Docker Compose > 2.3(注意是 v2 的 docker compose 子命令,不是老的 docker-compose 二进制)。
Ubuntu / Debian 用官方一键脚本最省事:
`bash
curl -fsSL https://get.docker.com | sudo sh
sudo systemctl enable --now docker
docker version
docker compose version
`
CentOS 7 走仓库安装,然后手动补 Compose v2 插件(这是 CentOS 7 上最容易漏的一步):
`bash
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl enable --now docker
sudo mkdir -p /usr/local/lib/docker/cli-plugins
COMPOSE_VER=v2.29.7
sudo curl -SL "https://github.com/docker/compose/releases/download/${COMPOSE_VER}/docker-compose-linux-x86_64" -o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
docker compose version
`
验证标准:docker version 能看到 Client 与 Server,docker compose version 输出 Docker Compose version v2.x。只要 docker compose 报 command not found,后面 ./install.sh 一定失败,先把这一步解决。
第 3 步:下载并校验 Harbor 安装包
Harbor 有两种安装包,按你的网络环境选:
- 在线安装包(online installer):体积很小,安装时从 Docker Hub 实时拉取所有 Harbor 组件镜像。适合机器能顺畅访问外网的场景。 - 离线安装包(offline installer):内嵌了所有预构建镜像,体积大得多(几百 MB),但安装时不依赖外网。适合网络受限、或要求可复现部署的生产环境。
不要写死版本号——用 GitHub API 取最新稳定版,避免教程发出去几个月后 wget 的链接 404:
`bash
VER=$(curl -s https://api.github.com/repos/goharbor/harbor/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+')
echo "最新稳定版: ${VER}"
wget "https://github.com/goharbor/harbor/releases/download/${VER}/harbor-offline-installer-${VER}.tgz"
wget "https://github.com/goharbor/harbor/releases/download/${VER}/harbor-offline-installer-${VER}.tgz.asc"
`
一定要校验安装包——镜像仓库是供应链的入口,被篡改的安装包等于把后门直接装进你的基础设施。两种校验方式,任选其一:
导入 Harbor 官方签名公钥并校验 .asc 签名(老方式,长期可用):
`bash
gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 644FF454C0B4115C
gpg -v --keyserver hkps://keyserver.ubuntu.com --verify harbor-offline-installer-${VER}.tgz.asc
`
从 v2.15.0 起,Harbor 的发布产物改用 Cosign 签名,若你装了 cosign 也可用它校验(官方 README 给了完整命令)。看到 Good signature / Verified OK 再继续。
解压:
`bash
tar xzvf harbor-offline-installer-${VER}.tgz
cd harbor
ls
`
解压后目录里的关键文件:harbor.yml.tmpl(配置模板)、install.sh(安装脚本)、prepare(生成 compose 的脚本)。不要直接改 harbor.yml.tmpl,复制成 harbor.yml 再改:
`bash
cp harbor.yml.tmpl harbor.yml
`
第 4 步:写 harbor.yml(配置核心)
harbor.yml 是 Harbor 唯一的系统级配置文件。下面是一份生产可用的最小配置(Harbor 官方模板里大量用 # 做注释,但本站的 Markdown 渲染器会把配置块里的井号当成标题,所以这里给出的是无注释的纯净版本,各字段含义见后面的表格):
`yaml
hostname: reg.yourdomain.com
http: port: 80
https: port: 443 certificate: /etc/harbor/ssl/reg.yourdomain.com.crt private_key: /etc/harbor/ssl/reg.yourdomain.com.key
harbor_admin_password: 这里换成你自己的强密码
database: password: 这里换成你自己的强密码
data_volume: /data
trivy: ignore_unfixed: false skip_update: false insecure: false
jobservice: max_job_workers: 10
log: level: info local: rotate_count: 50 rotate_size: 200M location: /var/log/harbor
_version: 2.15.0
`
各字段在干什么,看这张表比在 YAML 里写注释更可靠:
| 配置项 | 作用 | 必须注意 |
|---|---|---|
| hostname | 访问 Harbor 的地址(域名或 IP) | 绝不能填 localhost / 127.0.0.1 / 0.0.0.0——它要能被外部客户端访问。官方原文明确警告过这一点 |
| http.port | HTTP 端口,默认 80 | 若启用了 HTTPS,此端口会重定向到 HTTPS 端口 |
| https.port / certificate / private_key | HTTPS 端口与证书路径 | 生产必须用 HTTPS;证书与私钥路径要写绝对路径 |
| harbor_admin_password | 管理员初始密码 | 只在第一次启动时生效,之后改密码要去 Web 后台。默认是 admin / Harbor12345,务必改掉 |
| database.password | 内置 PostgreSQL 的密码 | 官方原话"生产使用前必须改"。默认是 root123 |
| data_volume | Harbor 数据落盘目录,默认 /data | 容器删了数据仍在;但要保证这个目录所在分区有足够空间 |
| trivy.* | 漏洞扫描器配置 | skip_update: true 用于离线/CI 环境避免 GitHub 限速,需手动挂载 trivy.db |
| storage_service | 存储后端 | 默认本地 filesystem,可切 s3 / oss / gcs / azure / swift |
| external_url | 通过外部反代访问时使用 | 启用后 hostname 不再参与拼接 |
| cache.enabled | Redis 缓存层 | 高并发拉取场景强烈建议开启,能显著降低重复请求的耗时 |
第 5 步:准备 HTTPS 证书
生产环境必须用 HTTPS——官方原话:不使用 HTTPS 只适用于没有外网连接的离线测试/开发环境,否则会暴露在中间人攻击下。Docker 客户端拉取私有镜像时,证书可信是默认前提。
推荐做法(生产首选):用你自己的域名申请 Let's Encrypt 证书(申请流程、DNS 验证、自动续期直接复用本站 Nginx 反代 + Let's Encrypt SSL 教程),把生成的 .crt 和 .key 放到服务器上,在 harbor.yml 里填绝对路径即可。Let's Encrypt 证书被操作系统和 Docker 客户端普遍信任,客户端不需要任何额外配置就能 push/pull。
自签证书(仅测试):官方文档也给了 OpenSSL 全套生成步骤——先建 CA,再用 CA 签服务器证书,注意必须生成 x509 v3 扩展文件并正确填写 SAN(Subject Alternative Name),DNS.1 填你的域名。自签证书的代价是:每台客户端都要把 CA 加进系统信任库,否则 docker login 会报 x509: certificate signed by unknown authority。生产环境别自找麻烦,直接上 Let's Encrypt。
第 6 步:一键安装并启动
Harbor 的安装本质是 install.sh 用模板生成 docker-compose.yml,再把一组容器拉起来。默认安装不含 Trivy;要用漏洞扫描就加 --with-trivy:
`bash
cd harbor
sudo ./install.sh --with-trivy
`
安装脚本会依次做:检查环境 → 根据 harbor.yml 渲染出 docker-compose.yml → 用 docker compose 拉起所有组件。在线安装包这一步会从 Docker Hub 拉镜像,可能要等几分钟;离线安装包则直接从本地加载,快得多。
安装完成后验证:
`bash
cd harbor
sudo docker compose ps
curl -sI https://reg.yourdomain.com | head -3
`
docker compose ps 里 core、portal、registry、jobservice、db、redis、nginx、trivy 等容器状态都应是 Up(有 healthy 更好)。若 curl 拿到 HTTP/2 200,说明内置 Nginx 已经接住请求了——Harbor 自带一个 Nginx 作为流量入口,你不需要再单独装一个。
第 7 步:登录、建项目、推拉镜像
浏览器打开 https://reg.yourdomain.com,用 admin 和你设的密码登录(第一次登录后立刻改密码)。先在界面里新建一个项目,比如 myproject(勾选私有则外部不可匿名拉取),然后回到命令行:
`bash
docker login reg.yourdomain.com
docker pull nginx:latest docker tag nginx:latest reg.yourdomain.com/myproject/nginx:latest docker push reg.yourdomain.com/myproject/nginx:latest
docker pull reg.yourdomain.com/myproject/nginx:latest
`
四条命令跑通,Harbor 就算真正可用了。几个要点:
- 用 HTTPS + 受信任证书时,客户端零配置——docker login 直接成功,这也是强烈推荐 Let's Encrypt 的原因。
- 若你坚持用 HTTP,必须在每台客户端的 /etc/docker/daemon.json 里加 "insecure-registries": ["reg.yourdomain.com:80"],然后 sudo systemctl restart docker。这正是官方反复强调"HTTP 只用于隔离的测试环境"的原因——每加一台机器都要改一次。
- 推送前先 tag,仓库路径的第一段就是 Harbor 里的项目名 myproject,项目必须先存在,否则 push 报 denied: requested access to the resource is denied。
第 8 步:把企业级能力真正用起来
装完只是开始,Harbor 的价值在下面三块。这三块是它和裸 registry:2 的分水岭。
(1)项目权限(RBAC):Harbor 的权限边界是"项目"。进入 myproject → 成员 → 添加用户,可以给不同人不同角色。角色从低到高大致是:访客(只读拉取)→ 开发者(可推拉)→ 维护者(可管理镜像)→ 项目管理员(可管成员)。团队里"只准拉、不准推"的机器,就用只读角色。
(2)机器人账号(Robot Account):CI 流水线不要用真人账号,而应在项目的"机器人账户"里创建一个专用账号,只授予它这个项目所需的推拉权限,并设置过期时间。这样即使 CI 凭据泄露,影响面也被限制在单个项目内,而且随用随吊销。
(3)漏洞扫描与阻断策略:配了 Trivy 之后,可以手动对某个镜像点"扫描",也能给项目设定时扫描策略(比如每天扫一次)。更关键的是"阻止易受攻击的镜像被拉取"策略——设置一个 CVE 严重级别阈值(例如存在 High 及以上未修复漏洞就拦),Harbor 会在拉取时直接拒绝。这条把"扫描报告"从"事后看看"变成了"上线前闸门",是 Harbor 最实用的一项能力。
(4)(可选)跨仓库复制:如果你在多个地域有机器,可以配一个"复制目标"(另一个 Harbor 实例,或云厂商的 ACR/TCR/ECR),再建一条复制规则(可按仓库名、标签过滤)。Harbor 会按规则把镜像同步过去,失败自动重试——这就是异地容灾和多地域分发的底座。镜像仓库单点一旦挂掉,整个团队的部署都会停摆,生产环境要么做复制,要么至少有异地备份。
第 9 步:垃圾回收(GC)——不配这步,磁盘迟早被撑爆
这是 Harbor 最容易踩的坑,没有之一。 官方文档白纸黑字写着:"当你删除镜像时,空间不会自动释放,你必须运行垃圾回收来删除不再被任何 manifest 引用的 blob。" 很多人删了一堆旧镜像,一看磁盘用量纹丝不动,就是因为没跑 GC。
GC 在 Web 界面操作:Administration → Clean Up → Garbage Collection 标签页。几个必须知道的细节:
| 项目 | 说明 | |---|---| | 工作线程(Workers) | 可设并行执行 GC 的线程数 | | 允许回收无标签制品 | 勾选后,无 tag 的制品也会被一并删除并回收(很多 CI 会推无 tag 的中间镜像,恰恰是主要的空间浪费源) | | DRY RUN(试运行) | 先点它——只打印将被删除的 blob 和大致释放空间,不动任何数据 | | GC Now | 立即执行;受频控,每分钟只能跑一次 | | 保护窗口 | GC 有一个 2 小时的时间窗口,最近 2 小时内上传的 layer 不会被动,避免误删正在上传的制品 | | 在线执行 | GC 不中断使用——跑的过程中仍可正常 push / pull / delete | | 定时执行 | 可设为 Hourly / Daily / Weekly / Custom(cron),生产环境建议每周或每天定时跑 | | 历史记录 | "Garbage Collection History" 表里能看每次运行的触发方式、状态、释放详情与日志 |
正确的使用姿势:① 删除镜像后跑 GC;② 上线前先 DRY RUN 看会删什么;③ 勾选"允许回收无标签制品",否则 CI 反复推的无 tag 镜像会一直堆积;④ 设成定时任务,别等磁盘满了才想起来。想手动触发,也可以进入 harbor 目录用 docker compose 执行维护命令,或用 Harbor 的 REST API。
五、安全加固、备份与升级
装好不等于安全。镜像仓库是供应链入口,一台被拿下的 Harbor 等于把后门分发给了整个团队。下面这些是必须做的。
5.1 五条安全红线
1. 改掉两个默认密码:admin 的初始密码 Harbor12345,和数据库默认密码 root123。官方文档对数据库密码的原话就是"生产使用前必须修改"。
2. 生产强制 HTTPS:HTTP 仅限隔离的测试环境。不开 HTTPS,凭据和镜像在网络上明文传输。
3. 端口只开 80/443:防火墙与云安全组双向收敛,别把 Harbor 内部的 db/redis 端口暴露出去。
4. 用机器人账号而非真人账号做 CI:按项目授予最小权限 + 设过期时间,泄露了也能即时吊销。
5. 定期扫描 + 阻断策略 + 定期 GC:把安全从"事后报告"变成"上线闸门",同时别让磁盘被旧层文件吃掉。
5.2 备份:三样东西缺一不可
Harbor 的备份没那么玄乎,关键是别只备份镜像:
| 要备份的东西 | 位置 | 说明 |
|---|---|---|
| 镜像层与制品数据 | data_volume(默认 /data) | 体积最大,可备份到对象存储/异机 |
| 配置文件 | harbor/harbor.yml | 纯文本,纳入 Git 管理最省事 |
| 数据库 | Harbor 内置 PostgreSQL 的数据卷 | 用户、项目、权限、扫描结果都在这里,最容易漏 |
一条最省心的策略:把 /data 整个目录 rsync 到另一台机器或 S3/OSS 桶,同时单独留一份 harbor.yml。如果存储后端已经切到对象存储(storage_service: s3/oss),那镜像数据天然就在外部,备份只需管数据库和配置。
5.3 升级不丢数据
Harbor 的升级流程是先备份、再换包、跑安装脚本:
`bash
cd harbor
sudo docker compose down
cd .. wget "https://github.com/goharbor/harbor/releases/download/${VER_NEW}/harbor-offline-installer-${VER_NEW}.tgz" tar xzvf harbor-offline-installer-${VER_NEW}.tgz
cd harbor
cp ../harbor-old/harbor.yml ./harbor.yml
diff harbor.yml.tmpl harbor.yml
sudo ./install.sh --with-trivy
`
升级前务必 docker compose down 并完成备份,特别是跨小版本时;harbor.yml 直接复用旧的(最好和新版 harbor.yml.tmpl 做一次 diff,看有没有新增字段)。数据在 /data 卷里,容器重建不会丢——但前提是你真的备份过。
5.4 自建 Harbor vs 云厂商托管仓库,怎么选
| 方案 | 成本口径 | 适合 | |---|---|---| | 自建 Harbor(本文) | 只有服务器费(2核4G 约 $20~$36/月),镜像存储与拉取不额外计费 | 团队规模中等、要审计/扫描/离线、想掌握数据 | | 云厂商托管(阿里云 ACR / 腾讯云 TCR / AWS ECR) | 按存储量 + 流量计费,另有企业版席位费 | 不想运维、且已经深度绑定某家云 | | Docker Hub 付费档 | 按私有仓库数或席位月付 | 个人/小团队、镜像量小 |
怎么选:运维能力够、镜像量大、或要求数据自持 → 自建 Harbor 边际成本最低;完全不想碰运维、团队只在一个云上 → 托管仓库更省心。到本站 5.chengzicloud.cloud 选购服务器,可以再省一笔。
六、常见问题 FAQ
Q1:Harbor 和 Docker Hub 是什么关系?能不能让 Harbor 自动缓存 Docker Hub 的镜像?
它们是竞争的两套仓库,但 Harbor 支持把某个上游仓库配成"代理缓存(proxy cache)":创建一个代理项目指向 Docker Hub(或任意兼容的 registry),第一次拉取时代理去上游取回并缓存在本地,之后同一个镜像直接从你的 Harbor 秒回。这既绕开了 Docker Hub 的匿名限速,又让生产机的拉取不再依赖跨境链路——是自建仓库里最实用的一项省钱能力。
Q2:docker login 报 x509: certificate signed by unknown authority 怎么办?
说明客户端不信任 Harbor 的证书。用 Let's Encrypt 等受信任 CA 签发的证书不会有这个问题;若你用的是自签证书,需要在每台客户端上把 CA 放进信任目录:
`bash
sudo mkdir -p /etc/docker/certs.d/reg.yourdomain.com
sudo cp ca.crt /etc/docker/certs.d/reg.yourdomain.com/ca.crt
sudo systemctl restart docker
`
根治办法是换受信任证书——这也是本文反复强调"生产用 Let's Encrypt"的原因。
Q3:push 报 denied: requested access to the resource is denied?
三个常见原因,按顺序查:① 目标项目不存在——Harbor 的镜像路径第一段就是项目名,必须先建项目;② 当前登录账号对该项目没有推送权限——用只读角色或访客账号推就会失败;③ 没登录或登错服务器——docker login reg.yourdomain.com 确认一下。
Q4:装完 Harbor 起不来,日志报 bind: address already in use?
80/443 被占了。最常见是机器上已经跑着 Nginx/Apache。解决办法:给 Harbor 换端口(改 harbor.yml 的 http.port / https.port),或停掉占端口的服务,让 Harbor 独占。注意改完要重新 ./install.sh 才会生效。
Q5:删了镜像,但 df -h 显示磁盘没变小?
这正是第四节第 9 步讲的坑——删除镜像不会自动释放空间,必须去 Administration → Clean Up → Garbage Collection 跑 GC。建议先 DRY RUN,再勾选"允许回收无标签制品"后正式执行,并设置定时任务。
Q6:1核1G 的小机器能跑 Harbor 吗?
不建议。 Harbor 官方给的最低资源要求是 2 CPU / 4GB 内存,它内部是一组容器(core、portal、db、redis、registry、jobservice、nginx,加 Trivy 还有 scanner),低于这个配置很容易出现容器反复重启或 OOM。个人试用至少 2核4G,正式使用 4核8G。
Q7:CentOS 7 能装吗?会不会遇到 glibc 版本不够的问题?
能,而且不会有 glibc 问题。 Harbor 全程容器化,宿主机的 glibc 不参与运行——所以 CentOS 7 只有 glibc 2.17 这件事对 Harbor 完全不是障碍(这与本站 code-server / Ollama / Meilisearch 篇的 glibc 坑正好相反)。CentOS 7 上唯一要手动补的是 Docker Compose v2 插件(见第 2 步)。
Q8:内网/离线服务器没有外网,Trivy 扫不了漏洞怎么办?
Trivy 的漏洞库默认从 GitHub 下载,离线环境有两个办法:① 在 harbor.yml 里把 trivy.skip_update 设为 true,然后手动下载 trivy-offline.tar.gz,解压出 trivy.db 和 metadata.json,挂载到容器内的 /home/scanner/.cache/trivy/db/ 路径;② 若只是偶尔被 GitHub 限速(匿名下载 60 次/小时),可在配置里设置 trivy.github_token 把限额提到 5000 次/小时。
Q9:升级 Harbor 会不会丢数据?
只要按第 5.3 节的流程走就不会——数据都在 /data 卷里。但升级前的 docker compose down 和完整备份绝不能省。若担心,可先在测试机用同样的 harbor.yml 跑一遍新版本,确认无误再动生产。
七、总结
用海外云服务器搭建 Harbor 私有镜像仓库,整条链路其实就是九步:买一台 SSD 机器 → 收敛 80/443 端口 → 装 Docker 与 Compose v2 → 下载并校验安装包 → 写 harbor.yml(记得改掉两个默认密码)→ 配 HTTPS 证书 → ./install.sh --with-trivy 一键安装 → 建项目、用机器人账号推拉镜像 → 配好垃圾回收和备份。一台 4核8G 的机器,换来的是团队镜像的"单一可信来源":推拉经过它,权限、扫描、审计就都只需在这一处做。
真正决定这套仓库好不好用的,不是命令,而是三个判断:第一,HTTPS 是必需品不是可选项——它决定客户端要不要到处改配置;第二,GC 必须配——官方默认删镜像不释放空间,不跑 GC 磁盘迟早爆;第三,CI 用机器人账号 + 最小权限——仓库是供应链的入口,凭据管理松一寸,风险就大一分。
最后回到它在本站容器家族里的位置:GitLab / Gitea 管"代码",Harbor 管"镜像制品",Docker + Portainer 管"单机容器怎么跑",Kubernetes 管"多机怎么编排"。四者拼在一起,才是一条从源码到上线的完整链路。把每一层的边界说清楚,比把某一个工具吹成万能更有价值。
延伸阅读: - Docker + Portainer 容器管理平台搭建完整教程 - GitLab CE + GitLab Runner CI/CD 私有代码托管完整教程 - Kubernetes (K8s) 集群搭建完整教程 - Gitea 轻量级自建 Git 服务器完整教程 - MinIO 自建对象存储完整教程(S3 兼容) - Nginx 反向代理 + Let's Encrypt 免费 SSL 证书配置完整教程
> 本文由 5.chengzicloud.cloud 提供,点击访问首页了解更多海外云服务器部署方案和专属优惠。