跳到主要内容
08:44:04
🔅🔆

harbor安装

harbor官网

harbor github地址

0.环境变量​

说明

本文所有命令统一引用下面这组环境变量,开始前先按需修改并执行一次(同一终端会话内有效,重开终端需重新 export 或写入 /etc/profile.d/harbor.sh)。注意版本、域名要与证书一致。

# ====== 环境变量(按需修改后统一执行一次) ======
export HARBOR_VERSION="2.16.0-rc1" # Harbor 版本(v2.16.0 正式版发布后可改为 2.16.0)
export HARBOR_INSTALLER_ARCH="amd64" # 安装包架构:uname -m 为 x86_64 填 amd64,aarch64 填 arm64
export HARBOR_HOSTNAME="harbor.ops.com" # 访问域名(需与证书 CN/SAN 一致)
export HARBOR_ADMIN_PASSWORD="Harbor12345" # admin 初始密码(仅首次启动生效)
export HARBOR_DB_PASSWORD="root123" # 内置 PostgreSQL root 密码
export HARBOR_HTTP_PORT="8080" # HTTP 访问端口
export HARBOR_INSTALL_DIR="/data/docker-project/harbor" # 安装根目录(程序与配置)
export HARBOR_DATA_DIR="/data/docker-volume/harbor" # 镜像数据存储目录(数据本体)

1.安装先决条件​

前置要求

Harbor 以 Docker Compose 方式运行,开始前服务器上必须已安装并启动 Docker(含 Docker Compose 插件),本笔记不再包含 Docker/Compose 的安装步骤。openssl、wget 为系统自带或常规软件。

硬件

资源最低推荐
cpu2c4c
内存4GB8GB
硬盘40GB160GB

软件

软件版本描述
docker17.06.0-ce+有关安装说明,请参阅 Docker 引擎文档
docker-composedocker-compose (v1.18.0+) 或 docker-compose v2 (docker-compose-plugin)有关安装说明,请参阅 Docker Compose 文档
Openssl最新版优先用于为Harbor生成证书和密钥

网络端口

端口协议描述
443HTTPSHarbor 门户和核心 API 在此端口上接受 HTTPS 请求。您可以在配置文件中更改此端口。
4443HTTPS连接到 Harbor 的 Docker Content Trust 服务。只有在启用 Notary 时才需要。您可以在配置文件中更改此端口。
80HTTPHarbor 门户和核心 API 在此端口上接受 HTTP 请求。您可以在配置文件中更改此端口。

2.下载安装包​

harbor安装包下载地址

说明

harbor有2种安装方式

  • 在线安装程序 :在线安装程序从 Docker hub 下载Harbor镜像,因此安装程序的体积非常小。安装包名称 harbor-online-installer-v{version}.tgz
  • 离线安装程序 :如果要部署 Harbor 的主机没有连接到 Internet,请使用离线安装程序。离线安装程序包含预构建的图像,因此它比在线安装程序大。安装包名称 harbor-offline-installer-v{version}.tgz
v2.16.0-rc1 只有离线包,且包名带架构后缀

v2.16.0 正式版尚未发布(当前最新 rc 为 v2.16.0-rc1,2026-10-27),从 v2.16.0-rc1 起官方只提供离线安装包,且包名带架构后缀:

  • x86_64 机器:harbor-offline-installer-v2.16.0-rc1-amd64.tgz(约 722MB)
  • aarch64 机器:harbor-offline-installer-v2.16.0-rc1-arm64.tgz(约 644MB)

离线包内置全部组件镜像,install.sh 会自动 docker load 后启动,运行时不依赖 Docker Hub(国内环境反而更省心)。版本选择参考官方 releases 页面:-dev 是开发分支夜间构建(无安装包,不建议用)、-rcN 是候选版、无后缀是正式版。

2.1 创建目录​

mkdir -p "${HARBOR_INSTALL_DIR}" && cd "${HARBOR_INSTALL_DIR}"

2.2 下载安装包​

# 安装包名带架构后缀(变量见第 0 节)
PKG="harbor-offline-installer-v${HARBOR_VERSION}-${HARBOR_INSTALLER_ARCH}.tgz"

wget https://github.com/goharbor/harbor/releases/download/v${HARBOR_VERSION}/${PKG}

2.3 验证包(可选)​

可下载相应 *.asc 文件以验证包是否为正版(部分版本如 v2.16.0-rc1 提供 *.sigstore.json 签名替代)

wget https://github.com/goharbor/harbor/releases/download/v${HARBOR_VERSION}/${PKG}.asc

2.4 解压缩安装包​

说明

安装包内顶层是一个 harbor/ 目录,--strip-components=1 用于去掉这一层,把 install.sh 等文件直接解压到 ${HARBOR_INSTALL_DIR} 本身(避免出现 harbor/harbor 两层)。

tar xf ${PKG} --strip-components=1

3.配置对harbor的https访问​

3.1 生成证书颁发机构证书​

3.1.1 创建证书存放目录​

# 当前目录为 /data/harbor/cert
mkdir cert && cd cert

3.1.2 生成ca证书私钥​

# 会生成 ca.key
$ openssl genrsa -out ca.key 4096
Generating RSA private key, 4096 bit long modulus
......................................................................................................................................++
..........................................................++
e is 65537 (0x10001)

3.1.3 生成ca证书​

# 会生成 ca.crt
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=ops/OU=ops/CN=harbor.ops.com" \
-key ca.key \
-out ca.crt

3.2 生成服务器证书​

3.2.1 生成私钥​

# 会生成 harbor.ops.com.key
openssl genrsa -out harbor.ops.com.key 4096

3.2.2 生成证书签名请求 (CSR)​

说明

调整选项中的值 -subj 以反映您的组织。如果使用 FQDN 连接 Harbor 主机,则必须将其指定为通用名称 ( CN) 属性,并在密钥和 CSR 文件名中使用它。

# 会生成 harbor.ops.com.csr
openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=ops/OU=ops/CN=harbor.ops.com" \
-key harbor.ops.com.key \
-out harbor.ops.com.csr

3.2.3 生成 x509 v3 扩展文件​

说明

无论您是使用 FQDN 还是 IP 地址连接到您的 Harbor 主机,您都必须创建此文件,以便您可以为您的 Harbor 主机生成符合主题备用名称 (SAN) 和 x509 v3 的证书扩展要求。替换 DNS 条目以反映您的域。

cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=harbor.ops.com
DNS.2=harbor.ops
DNS.3=harbor
EOF

3.2.4 使用 v3.ext 文件生成证书​

# 会生成 ca.srl 和 harbor.ops.com.crt
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in harbor.ops.com.csr \
-out harbor.ops.com.crt

3.3 向harbor和docker提供证书​

生成 ca.crt 、 yourdomain.com.crt 和 yourdomain.com.key 文件后,必须将它们提供给 Harbor 和 Docker,并重新配置 Harbor 以使用它们。

3.3.1 转换 .crt 为 .cert​

说明

Docker 守护进程将 .crt 文件解释为 CA 证书,.cert 将文件解释为客户端证书。

# 转换证书文件
openssl x509 -inform PEM -in harbor.ops.com.crt -out harbor.ops.com.cert

3.3.3 将服务器证书、密钥和 CA 文件复制到 Harbor 主机上的 Docker 证书文件夹中​

说明

如果您将默认的nginx端口443映射到其他端口,请创建 /etc/docker/certs.d/yourdomain.com:port或 /etc/docker/certs.d/harbor_IP:port 文件夹。

# 创建目录
[ -d /etc/docker/certs.d/harbor.ops.com ] || mkdir -p /etc/docker/certs.d/harbor.ops.com

# 拷贝证书文件
cp harbor.ops.com.cert /etc/docker/certs.d/harbor.ops.com/
cp harbor.ops.com.key /etc/docker/certs.d/harbor.ops.com/
cp ca.crt /etc/docker/certs.d/harbor.ops.com/

3.3.4 重启docker​

systemctl restart docker

4.部署harbor​

4.1 配置harbor yml文件​

harbor在线安装包解压后会有一个 harbor.yml.tmpl 示例配置文件

将此文件重命名为 harbor.yml 来设置系统级参数。 这些参数在运行 install.sh 脚本以安装或重新配置 Harbor 时生效。

在初始部署和启动 Harbor 之后,可以在 Harbor Web Portal 中执行其他配置。

4.1.1 参数说明​

4.1.1.1 必要参数​
  • hostname : 指定要部署 Harbor 的目标主机的 IP 地址或完全限定域名 (FQDN)。这是您访问 Harbor Portal 和注册服务的地址。例如,192.168.1.10或reg.yourdomain.com。注册表服务必须可供外部客户端访问,因此不要将localhost、127.0.0.1或指定0.0.0.0为主机名。

  • http : 不要在生产环境中使用http,只有在没有连接到外部互联网的测试或开发环境才可以使用http。

    • port : 用于 Harbor 门户和 Docker 命令的 HTTP 端口号。默认值为 80。
  • https : 使用 HTTPS 访问 Harbor Portal 和令牌/通知服务。

    • port : 用于 Harbor 门户和 Docker 命令的 HTTPS 端口号。默认值为 443。

    • certificate : SSL 证书的路径。

    • private_key : SSL 密钥的路径。

  • internal_tls : 使用 HTTPS 在 Harbor 组件之间进行通信

    • enabled : 将此标志设置为true表示已启用内部 tls
    • dir : 包含内部证书和密钥的目录的路径
  • harbor_admin_password : 设置Harbor系统管理员的初始密码。此密码仅在 Harbor 首次启动时使用。在随后的登录中,此设置将被忽略,管理员密码将在 Harbor 门户中设置。默认的用户名和密码是admin和Harbor12345。

  • database : 使用本地 PostgreSQL 数据库。您可以选择配置外部数据库,在这种情况下您可以停用此选项。

    • password : 设置本地数据库的root密码。
    • max_idle_conns : 空闲连接池中的最大连接数。如果它 <=0,则不保留空闲连接。
    • max_open_conns : 到数据库的最大打开连接数。如果 <= 0,则打开的连接数没有限制。
    • conn_max_lifetime : 可以重用连接的最长时间。如果它 <= 0,则连接不会由于连接的年龄而关闭。
    • conn_max_idle_time : 连接空闲的最长时间。如果它 <= 0,则连接不会由于连接的空闲时间而关闭。
  • data_volume : 目标主机上存储 Harbor 数据的位置。即使删除 和/或 重新创建 Harbor 的容器,此数据也保持不变。您可以选择配置外部存储,在这种情况下停用此选项并启用storage_service。默认值为/data。

  • trivy : 配置 Trivy 扫描仪。

    • ignore_unfixed : 将标志设置为true仅显示已修复的漏洞。默认值为false
    • security_check : 要检测的安全问题的逗号分隔列表。可能的值为vuln,config和secret。默认为vuln.
    • skip_update : 您可能希望在测试或 CI/CD 环境中启用此标志以避免 GitHub 速率限制问题。如果启用该标志,您必须trivy-offline.tar.gz手动下载存档,提取和trivy.db文件metadata.json并将它们安装在/home/scanner/.cache/trivy/db/trivy.db容器中的路径中。默认值为false
    • insecure : 将标志设置为true跳过验证注册表证书。默认值为false
    • github_token : 设置 GitHub 访问令牌以下载 Trivy DB。Trivy DB 由 Trivy 从 GitHub 发布页面下载。来自 GitHub 的匿名下载受每小时 60 次请求的限制。通常这样的速率限制足以用于生产操作。如果出于任何原因这还不够,您可以通过指定 GitHub 访问令牌将速率限制提高到每小时 5000 个请求。有关 GitHub 速率限制的更多详细信息,请参阅 https://developer.github.com/v3/#rate-limiting 。您可以按照 https://help.github.com/en/github 中的说明创建 GitHub 令牌/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
  • jobservice

    • max_job_workers : 作业服务中复制工作者的最大数量。对于每个图像复制作业,工作人员将存储库的所有标签同步到远程目标。增加这个数字允许系统中有更多的并发复制作业。但是,由于每个worker都会消耗一定的网络/CPU/IO资源,所以根据宿主机的硬件资源来设置该属性的值。默认值为 10。
    • max_job_duration_hours : 单个任务最长允许运行时间(单位:小时)
    • job_loggers : 任务日志输出方式
      • STD_OUTPUT : 输出到容器标准输出(docker logs 可查看)
      • FILE : 同时写入本地日志文件 /var/log/harbor
  • notification

    • webhook_job_max_retry : 设置 Web 挂钩作业的最大重试次数。默认值为 10。
  • log : 配置日志记录。Harbor 使用 rsyslog 来收集每个容器的日志。

    • level : 将日志记录级别设置为debug、info、warning、error或fatal。默认值为info。
    • local : 设置日志保留参数
      • rotate_count``rotate_count : 日志文件在被删除之前会轮换几次。如果计数为 0,旧版本将被删除而不是轮换。默认值为 50。
      • rotate_size : 日志文件只有在大于rotate_size字节时才会轮换。用于k千字节、M兆字节和G千兆字节。 100、100k和100M都是100G有效值。默认为 200M。
      • location : 设置日志存放目录。默认值为/var/log/harbor。
    • external_endpoint : 启用此选项可将日志转发到系统日志服务器。
      • protocol : 系统日志服务器的传输协议。默认为 TCP。
      • host : 系统日志服务器的 URL。
      • port : syslog服务器监听的端口
  • proxy : 配置由 trivy-adapter、复制作业服务和 Harbor 使用的代理。如果不需要代理,请留空。有些代理有白名单设置,如果启用了Trivy,你需要将以下url添加到代理服务器白名单中:github.com, github-releases.githubusercontent.com, 和*.s3.amazonaws.com.

    • http_proxy : 配置 HTTP 代理,例如 http://my.proxy.com:3128
    • https_proxy : 配置 HTTPS 代理,例如 http://my.proxy.com:3128
    • no_proxy : 配置何时不使用代理,例如127.0.0.1,localhost,core,registry
  • cache : 为您的 Harbor 实例配置缓存层。启用后,Harbor 将使用 Redis 缓存一些 Harbor 资源(例如,工件、项目或项目元数据),从而减少重复请求同一 Harbor 资源所花费的时间和资源。强烈建议您在高并发拉取请求率的 Harbor 实例上启用此功能,以提高 Harbor 的整体性能。有关缓存层实现和性能改进的更多详细信息,请参阅缓存层维基页面。

    • enabled : 默认为false,设置为true启用 Harbor 的缓存层。
    • expire_hours : 以小时为单位配置缓存过期限制。默认值为 24。
4.1.1.2 可选参数​
  • external_url : 启用此选项以使用外部代理。启用后,不再使用主机名。

  • storage_service : 默认情况下,Harbor 将图像和图表存储在本地文件系统中。在生产环境中,您可能希望使用另一个存储后端而不是本地文件系统。下面列出的参数是注册表的配置。有关如何配置不同后端的更多信息,请参阅下面 配置存储后端

    • ca_bundle : 自定义根 CA 证书的路径,该证书被注入到注册表和图表存储库容器的信任库中。如果内部存储使用自签名证书,通常需要这样做。
    • filesystem : 默认是 filesystem,但是你可以设置 azure 、gcs 、s3 、swift 和 oss 。有关如何配置其他后端的信息,请参阅下面的 配置存储后端 。设置 maxthreads 以限制外部提供程序的线程数。 默认值为 100
    • redirect : 设置deactivate为true 表示停用注册表重定向
  • external_database : 如果停用本地数据库选项,则配置外部数据库设置。目前,Harbor 仅支持 PostgreSQL 数据库。必须创建 Harbor core, Notary server, 和Notary signer 3个数据库,表是在harobr启动的时候自动生成的。

    • harbor : 为 Harbor 数据配置外部数据库。
      • host: Harbor 数据库的主机名。
      • port:数据库端口。
      • db_name: 数据库名称。
      • username: 数据库用户名。
      • password:数据库密码。
      • ssl_mode:启用 SSL 模式。
      • max_idle_conns:空闲连接池中的最大连接数。如果 <=0,则不保留空闲连接。默认值为 2。
      • max_open_conns: 数据库的最大打开连接数。如果 <= 0,则打开的连接数没有限制。默认值为 0。
    • notary_signer : 为 Notary 签名者数据库配置外部数据库
      • host:公证签名者数据库的主机名
      • port:数据库端口。
      • db_name: 数据库名称。
      • username:连接到公证签名者数据库的用户名。
      • password:连接到公证签名者数据库的用户的密码。
      • ssl_mode:启用 SSL 模式。
    • notary_server :
      • host:公证服务器数据库的主机名。
      • port:数据库端口。
      • db_name: 数据库名称。
      • username:连接到公证服务器数据库的用户名。
      • password:连接到公证服务器数据库的用户的密码。
      • ssl_mode: 启用 SSL 模式。
  • external_redis : 配置外部 Redis 实例。

    • host : 外部 Redis 主机名。格式是 redis_host:redis_port 在1.10版本中 host 和 port 是单独写的,新版本中可以把主机名和端口写在一起。如果你使用的是哨兵模式,这部分应该是 host_sentinel1:port_sentinel1 , host_sentinel2:port_sentinel2 。
    • sentinel_master_set : 仅在使用 Sentinel 模式时设置此项
    • password : 外部 Redis 密码。
    • registry_db_index : Harbor 注册表的数据库索引。
    • jobservice_db_index : 作业服务的数据库索引。
    • chartmuseum_db_index : chart museum的数据库索引(中文不知道什么意思)。
    • trivy_db_index : Trivy 适配器的数据库索引。
  • metric : 配置将 Harbor 实例指标公开到指定的端口和路径

    • enabled : 通过将其设置为 true 在harbor上开启 metric 指标,默认是 false
    • port : metric 指标暴露端口,默认是 9090
    • path : metric 指标路径,默认是 /metrics
  • trace : 配置公开分布式跟踪数据

    • enabled : 通过将其设置为 true 在harbor上开启跟踪,默认是 false
    • sample_rate : 设置跟踪的采样率。例如,如果您想采样 100% 的跟踪数据,请将 sample_rate 设置为1;设置为 0.5 表示采样 50% 的跟踪数据
    • namespace : Namespace 用来区分不同的 Harbor 服务,会设置为带有 key 的属性 service.namespace
    • attributes : 属性是一个键值字典,包含用户定义的自定义属性,用于初始化跟踪提供程序,所有这些属性都将添加到跟踪数据中
    • jaeger :
      • endpoint:端点的url(例如http://127.0.0.1:14268/api/traces)。设置端点意味着通过 http 导出到 jaeger collector。
      • username::用于连接端点的用户名。如果不需要,留空。
      • password::用于连接端点的密码。如果不需要,留空。
      • agent_host: jaeger 代理的主机名。设置agent_host表示通过udp将数据导出到jaeger agent。
      • agent_port:: jaeger 代理的端口名称。
    • otel :
      • endpoint:otel compitable后端的主机名和端口(例如127.0.0.1:4318)。
      • url_path::端点的url路径(例如127.0.0.1:4318)
      • compression::如果启用数据压缩
      • insecure:忽略otel后端的证书验证
      • timeout::数据传输超时

4.1.2 编辑配置文件​

# 以下命令依赖第 0 节的环境变量(heredoc 未加引号,${VAR} 会被 shell 展开)
cat > harbor.yml << EOF
# 指定harbor访问域名
hostname: ${HARBOR_HOSTNAME}

# 指定http端口
http:
port: ${HARBOR_HTTP_PORT}

# 指定admin密码
harbor_admin_password: ${HARBOR_ADMIN_PASSWORD}

# 指定数据库相关信息,默认使用本地PostgrsSQL,如果要使用外置数据库则需要修改 external_database 配置项并注释 database 配置项
database:
password: ${HARBOR_DB_PASSWORD}

# 空闲连接池最大连接数,如果设置小于等于0则为不保留空闲连接
max_idle_conns: 100

# 数据库最大连接数,如果设置小于等于0则为不限制
max_open_conns: 900

# 可重用连接的最长时间,如果设置小于等于0则不会由于连接的时间而关闭
conn_max_lifetime: 5m

# 连接空闲最长时间,如果设置小于等于0则连接不会由于连接的空闲时间而关闭
conn_max_idle_time: 0

# 默认的数据存储路径,如果要使用外置存储,则需要修改 storage_service 配置项
data_volume: ${HARBOR_DATA_DIR}

# 配置 Trivy 扫描仪,Trivy DB包含来自NVD, Red Hat和许多其他上游漏洞数据库的漏洞信息,它是由Trivy从GitHub发布页面https://github.com/aquasecurity/trivy-db/releases 下载并缓存到本地系统文件
trivy:
# 设置为 true 仅显示已修复的漏洞
ignore_unfixed: false

# 是否跳过自动更新
skip_update: false

# 扫描jar文件和pom.xml在联网的情况下效果会更好,此选项设置为false则阻止Trivy发送API请求来识别依赖项且不执行离线扫描
offline_scan: false

# 要检测的安全问题的逗号分隔列表,值有 vuln、config、secret
security_check: vuln

# 是否跳过验证注册表证书
insecure: false


jobservice:
# 用于harbor镜像复制的最大worker数
max_job_workers: 10

# 单个任务最长允许运行时间(单位:小时)
max_job_duration_hours: 24

# 任务日志输出方式
job_loggers:
- STD_OUTPUT # 输出到容器标准输出(docker logs 可查看)
- FILE # 同时写入本地日志文件 /var/log/harbor

# jobLogger清理的持续时间,单位是天,如果设置为stdout则忽略
logger_sweeper_duration: 1

notification:
# webhook的最大重试次数
webhook_job_max_retry: 3

# webhook客户端连接超时时间,单位是秒
webhook_job_http_client_timeout: 3

# 日志配置
log:
# 指定日志级别,可选的有 debug、info、warning、error、fatal
level: info

# 设置日志保留参数
local:
# 保留切割日志的数量,如果设置为0,旧的日志将被删除
rotate_count: 50

# 指定日志多大才会被切割
rotate_size: 200M
location: /var/log/harbor

# harbor的版本
_version: ${HARBOR_VERSION}

# 相关代理配置
proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- trivy

# 清理 registry 临时上传目录
upload_purging:
enabled: true
age: 168h
interval: 24h
dryrun: false

# 缓存配置
cache:
# 默认不开启,如果开启后harbor将使用redis缓存一些资源,如果有高并发拉取的情况应该启用缓存
enabled: true

# 缓存过期时间,单位是小时
expire_hours: 24
EOF

4.2 执行安装​

执行 install.sh 会根据 harbor.yml 生成 docker-compose.yml 然后启动容器

./install.sh

安装成功后会在最后提示如下信息

✔ ----Harbor has been installed and started successfully.----
修改容器内时区

启动的容器默认使用的是 UTC 时间,./install 执行成功后会生成 docker-compose.yml 文件,可以修改 docker-compose.yml ,在各个容器的 volemes 下增加如下配置,然后重启就可以让容器内的时区变为 CST

- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime

4.3 查看安装​

$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
harbor-core goharbor/harbor-core:v2.14.2 "/harbor/entrypoint.…" core 12 minutes ago Up 12 minutes (healthy)
harbor-db goharbor/harbor-db:v2.14.2 "/docker-entrypoint.…" postgresql 12 minutes ago Up 12 minutes (healthy)
harbor-jobservice goharbor/harbor-jobservice:v2.14.2 "/harbor/entrypoint.…" jobservice 12 minutes ago Up 12 minutes (healthy)
harbor-log goharbor/harbor-log:v2.14.2 "/bin/sh -c /usr/loc…" log 12 minutes ago Up 12 minutes (healthy) 127.0.0.1:1514->10514/tcp
harbor-portal goharbor/harbor-portal:v2.14.2 "nginx -g 'daemon of…" portal 12 minutes ago Up 12 minutes (healthy)
nginx goharbor/nginx-photon:v2.14.2 "nginx -g 'daemon of…" proxy 12 minutes ago Up 12 minutes (healthy) 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
redis goharbor/redis-photon:v2.14.2 "redis-server /etc/r…" redis 12 minutes ago Up 12 minutes (healthy)
registry goharbor/registry-photon:v2.14.2 "/home/harbor/entryp…" registry 12 minutes ago Up 12 minutes (healthy)
registryctl goharbor/harbor-registryctl:v2.14.2 "/home/harbor/start.…" registryctl 12 minutes ago Up 12 minutes (healthy)

会启动如下容器

$ docker compose ps --format '{{.Names}}'
harbor-core
harbor-db
harbor-jobservice
harbor-log
harbor-portal
nginx
redis
registry
registryctl

启动的容器及作用

容器作用
nginx充当了 Harbor 的反向代理和负载均衡器。Nginx 容器会将所有的 HTTPS 流量路由到 Harbor 的 Web 界面和 API 服务上,并将 HTTP 流量重定向到 HTTPS。此外,Nginx 容器还提供了访问 Harbor Docker Registry 的代理,它会将所有的 Docker Registry 流量路由到 Registry 容器上
harbor-jobservice运行 Harbor 的任务服务,用于异步处理 Harbor 的一些任务,如 GC(垃圾回收)等
harbor-core运行 Harbor 的核心服务,包括 Web 界面、API、Webhook 等
registry运行 Docker Registry,用于存储和管理 Docker 镜像
harbor-portal容器。该容器运行 Harbor 的 Web 界面,提供用户界面和 API 服务,以便用户可以使用 Harbor 私有仓库管理和存储 Docker 镜像
harbor-db运行PostgreSQL 数据库,用于存储 Harbor 的元数据和配置信息
registryctl运行 Harbor 的控制台,用于管理和监控 Harbor
redis运行 Redis,用于存储 Harbor 的缓存信息
harbor-log运行 Harbor 的日志服务,用于收集、存储和查询 Harbor 的日志信息

5.其他​

5.1 配置http访问harbor​

说明

如果不想要配置https访问harbor或者访问入口是nginx/云厂商lb等(一般都是在nginx或lb上配置证书)则不需要执行 3 步骤中的内容

同时在docker的配置文件 /etc/docker/daemon.json 中还要指定配置使用http推送镜像

{
"insecure-registries" : ["harbor仓库地址", "0.0.0.0"]
}

5.2 配置存储后端​

默认情况下,Harbor 使用本地存储作为注册表,可以通过修改 harbor.yml 中的 storage_service 来指定使用的外部存储,有关如何为不同存储提供程序配置注册表存储后端的信息,请参阅 Docker 文档中的注册表配置参考

5.2.1 阿里云oss的配置示例​

storage_service:
oss:
# 必需项,指定accesskeyid
accesskeyid:

# 必需项,指定accesskeysecret
accesskeysecret:

# 必需项,指定OSS region 名称
region:

# 必需项,OSS bucket 名称
bucket:

# 非必需项,指定 endpoints 域名地址,有内网和公网
endpoint:

# 非必需项,指定内网访问还是外网访问,默认为 false
internal:

# 非必需项,是否启动服务端加密,默认为 false
encrypt:

# 非必需项,指定用于加密的可选 KMS 密钥 ID
encryptionkeyid:

# 非必需项,指定是否通过 ssl 将数据传输到存储桶,默认为 true
secure:

# 非必需项,分段上传(由 WriteStream 执行)到 OSS 的默认分段大小,默认值为 10 MB,OSS 的最小部分大小为 5MB
chunksize:

# 非必需项,存储所有注册表文件的根目录树,默认是空字符串(即桶的根)
rootdirectory:

参数说明,可以参考这个 文档

参数说明是否必须
accesskeyid指定access key ID✅
accesskeysecret指定access key secret✅
region指定oss的region,可以从阿里云访问域名和数据中心帮助文档查看✅
bucket指定使用的oss的bucket名称✅
endpoint默认是 [bucket].[region].aliyuncs.com 或[bucket].[region]-internal.aliyuncs.com否
internal指定内网还是外网访问,默认是 false ,阿里云访问域名和数据中心帮助文档查看否
encrypt指定是否在服务器端加密数据,默认为 false否
secure指定是否通过 ssl 将数据传输到存储桶,默认为 true否
chunksize分段上传(由 WriteStream 执行)到 OSS 的默认分段大小,默认值为 10 MB,OSS 的最小部分大小为 5MB否
rootdirectory存储所有注册表文件的根目录树,默认是空字符串(即桶的根)否

5.2.2 使用aws s3的配置示例​

storage_service:
s3:

参数说明,可以参考这个 文档

参数说明是否必须
accesskeyaws访问密钥,如果使用IAM 角色,请忽略从 IAM 获取临时凭证否
secretkeyaws密钥,如果使用IAM 角色,请忽略从 IAM 获取临时凭证否
region存储桶所在区域✅
bucket存储桶名称✅
regionendpoints3兼容存储服务(Minio等)的端点否
encrypt指定注册表是否以加密格式存储图像,默认为 false否
keyid用于加密的可选 KMS 密钥 ID(encrypt 必须为 true,否则将忽略此参数),默认为 none否
secure是否使用 HTTPS 而不是 HTTP,默认为 true否
skipverify当值设置为 true 时跳过 TLS 验证,默认为 false否
v4auth注册表是否使用 AWS 身份验证的版本 4,默认值为true否
chunksizeS3 API 要求分段上传块至少为 5MB,该值应该是大于 5 * 1024 * 1024 的数字否
rootdirectory这是应用于所有 S3 密钥的前缀,以允许在必要时对存储桶中的数据进行分段否
storageclass应用于每个注册表文件的 S3 存储类,默认值为 STANDARD否
accelerate注册表是否应使用 S3 Transfer Acceleration,在使用此选项之前,必须在存储桶上启用加速端点,默认为 false否

6.一键快速安装脚本(可重复执行)​

脚本特点
  • 幂等可重复执行:每一步都先检测(Docker 已装则跳过、安装包已解压则跳过下载、harbor.yml 已存在则保留不覆盖、证书已存在则跳过生成、容器已在运行则跳过安装),中途失败修复后直接重跑即可,失败即停(set -e)
  • 三种访问模式一键切换(DEPLOY_MODE 变量):http 纯 HTTP / https-lb 生产 LB 终止 TLS / https 自签证书模拟 HTTPS
  • 自动检测 CPU 架构(x86_64 → amd64 包,aarch64 → arm64 包)
  • 只需改脚本开头的变量区即可适配自己的环境
三种模式说明与切换方法
  • http:最简单,但客户端必须配 insecure-registries(否则报错 http: server gave HTTP response to HTTPS client),官方仅建议无外网的测试/内网环境
  • https-lb(生产推荐):证书配在入口 LB 上,Harbor 本机保持 HTTP;harbor.yml 写 external_url 告知外部地址。LB 转发时要保留 Host 头并加 X-Forwarded-Proto: https
  • https:脚本自动生成自签 CA 和服务端证书(SAN 同时含域名和本机 IP,两种方式访问都行),harbor.yml 监听 443;客户端节点需信任 ca.crt,脚本最后会打印 docker / containerd 的具体信任命令
  • 切换模式:docker compose down && rm -f harbor.yml 后重跑脚本(已生成的证书会保留复用,不会重复生成)
cat > harbor_quick_install.sh <<'EOF'
#!/bin/bash
#=============================================================
# Harbor 一键快速安装脚本(幂等,可重复执行,失败即停)
# 适用: CentOS/RHEL 7+/Rocky 等 yum 系
# 用法: bash harbor_quick_install.sh
#=============================================================
set -e

# ---------------- 可按需修改的变量 ----------------
HARBOR_VERSION="2.16.0-rc1" # Harbor 版本
HARBOR_HOSTNAME="harbor.ops.com" # 访问域名(客户端需能解析到本机或经 LB)
HARBOR_SERVER_IP="10.0.0.100" # 本机 IP(留空则自动获取;https 模式会写入证书 SAN)
ADMIN_PASSWORD="Harbor12345" # admin 初始密码(仅首次生效)
DB_PASSWORD="root123" # 内置 PostgreSQL root 密码
HTTP_PORT="8080" # HTTP 访问端口(http / https-lb 模式使用)
DATA_VOLUME="/data/docker-volume/harbor" # 镜像数据存储目录
INSTALL_DIR="/data/docker-project/harbor" # 安装根目录(程序与配置)

# 访问模式(三选一):
# http 纯 HTTP,最简单;客户端必须配 insecure-registries,仅内网/测试
# https-lb 生产环境推荐:入口 LB 上配置证书终止 TLS,Harbor 本机保持 HTTP
# https 测试环境模拟 HTTPS:本机自签证书监听 443,客户端需信任 ca.crt
DEPLOY_MODE="https"

err(){ echo -e "\n[ERROR] $*" >&2; exit 1; }
ok(){ echo "[ OK ] $*"; }

[ "$(id -u)" -eq 0 ] || err "请用 root 执行本脚本"

case "${DEPLOY_MODE}" in
http|https-lb|https) ok "访问模式: ${DEPLOY_MODE}" ;;
*) err "DEPLOY_MODE 只能是 http / https-lb / https,当前: ${DEPLOY_MODE}" ;;
esac

# 自动检测安装包架构(安装包名带架构后缀)
case "$(uname -m)" in
x86_64) INSTALLER_ARCH="amd64" ;;
aarch64) INSTALLER_ARCH="arm64" ;;
*) err "不支持的 CPU 架构: $(uname -m),仅支持 x86_64/aarch64" ;;
esac
ok "CPU 架构: $(uname -m) -> 安装包架构: ${INSTALLER_ARCH}"

# ---------- 1. Docker ----------
if command -v docker >/dev/null 2>&1; then
ok "Docker 已安装: $(docker --version)"
else
echo ">>> 安装 Docker ..."
yum install -y yum-utils || err "yum-utils 安装失败"
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y install docker-ce || err "docker-ce 安装失败"
systemctl enable --now docker
ok "Docker 安装完成"
fi

# 已有的 daemon.json 中若还配置了失效的阿里云镜像加速地址则提醒
if [ -f /etc/docker/daemon.json ] && grep -q "mirror.aliyuncs.com" /etc/docker/daemon.json 2>/dev/null; then
cat <<EOF2
[提示] /etc/docker/daemon.json 中配置的 mirror.aliyuncs.com 镜像加速地址已失效,
建议手动删除该配置项后执行 systemctl restart docker。
EOF2
fi

# ---------- 2. Docker Compose ----------
if docker compose version >/dev/null 2>&1; then
ok "Docker Compose 插件已安装: $(docker compose version)"
elif command -v docker-compose >/dev/null 2>&1; then
ok "docker-compose 已安装: $(docker-compose --version)"
else
echo ">>> 安装 docker-compose-plugin ..."
yum -y install docker-compose-plugin || err "docker-compose-plugin 安装失败"
ok "Docker Compose 安装完成"
fi

# ---------- 3. 下载并解压安装包(已存在则跳过) ----------
mkdir -p "${INSTALL_DIR}"
cd "${INSTALL_DIR}"
PKG="harbor-offline-installer-v${HARBOR_VERSION}-${INSTALLER_ARCH}.tgz"
if [ -f "${INSTALL_DIR}/install.sh" ]; then
ok "安装包已解压(${INSTALL_DIR}),跳过下载"
else
echo ">>> 下载 ${PKG}(约 700MB,GitHub 直连较慢请耐心)..."
wget -q --show-progress -O "${INSTALL_DIR}/${PKG}" \
"https://github.com/goharbor/harbor/releases/download/v${HARBOR_VERSION}/${PKG}" \
|| err "下载失败。可手动下载 ${PKG} 放到 ${INSTALL_DIR} 后重跑本脚本"
# --strip-components=1: 去掉包内顶层 harbor/ 目录,直接解压到 ${INSTALL_DIR}
tar xf "${PKG}" --strip-components=1
fi

cd "${INSTALL_DIR}"

# ---------- 4. https 模式:生成自签 CA 与服务端证书(已存在则跳过) ----------
CERT_DIR="/data/cert"
if [ "${DEPLOY_MODE}" = "https" ]; then
if [ -z "${HARBOR_SERVER_IP}" ]; then
HARBOR_SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
fi
[ -n "${HARBOR_SERVER_IP}" ] || err "无法自动获取本机 IP,请手动设置 HARBOR_SERVER_IP"
if [ -f "${CERT_DIR}/${HARBOR_HOSTNAME}.crt" ] && [ -f "${CERT_DIR}/ca.crt" ]; then
ok "自签证书已存在(${CERT_DIR}),跳过生成"
else
echo ">>> 生成自签证书(SAN: DNS=${HARBOR_HOSTNAME}, IP=${HARBOR_SERVER_IP})..."
mkdir -p "${CERT_DIR}" && cd "${CERT_DIR}"
[ -f ca.key ] || openssl genrsa -out ca.key 4096
[ -f ca.crt ] || openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=ops/OU=ops/CN=harbor-ca" \
-key ca.key -out ca.crt
[ -f "${HARBOR_HOSTNAME}.key" ] || openssl genrsa -out "${HARBOR_HOSTNAME}.key" 4096
[ -f "${HARBOR_HOSTNAME}.csr" ] || openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=ops/OU=ops/CN=${HARBOR_HOSTNAME}" \
-key "${HARBOR_HOSTNAME}.key" -out "${HARBOR_HOSTNAME}.csr"
cat > v3.ext <<EOF2
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=${HARBOR_HOSTNAME}
IP.1=${HARBOR_SERVER_IP}
EOF2
openssl x509 -req -sha512 -days 3650 -extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in "${HARBOR_HOSTNAME}.csr" -out "${HARBOR_HOSTNAME}.crt"
# Docker 守护进程把 .crt 当 CA 证书、.cert 当客户端证书,需转换一份
openssl x509 -inform PEM -in "${HARBOR_HOSTNAME}.crt" -out "${HARBOR_HOSTNAME}.cert"
cd "${INSTALL_DIR}"
ok "自签证书已生成: ${CERT_DIR}"
fi
fi

# ---------- 5. 生成 harbor.yml(已存在则保留原配置,不覆盖) ----------
if [ -f harbor.yml ]; then
ok "harbor.yml 已存在,保留现有配置不覆盖(切换 DEPLOY_MODE 需先 rm -f harbor.yml 再重跑)"
else
# 按模式生成访问配置段
if [ "${DEPLOY_MODE}" = "https" ]; then
ACCESS_BLOCK="https:
port: 443
certificate: /data/cert/${HARBOR_HOSTNAME}.crt
private_key: /data/cert/${HARBOR_HOSTNAME}.key"
elif [ "${DEPLOY_MODE}" = "https-lb" ]; then
ACCESS_BLOCK="external_url: https://${HARBOR_HOSTNAME}
http:
port: ${HTTP_PORT}"
else
ACCESS_BLOCK="http:
port: ${HTTP_PORT}"
fi
cat > harbor.yml <<EOF2
hostname: ${HARBOR_HOSTNAME}

# 访问配置(模式: ${DEPLOY_MODE})
${ACCESS_BLOCK}

harbor_admin_password: ${ADMIN_PASSWORD}

database:
password: ${DB_PASSWORD}
max_idle_conns: 100
max_open_conns: 900
conn_max_lifetime: 5m
conn_max_idle_time: 0

data_volume: ${DATA_VOLUME}

trivy:
ignore_unfixed: false
skip_update: false
offline_scan: false
security_check: vuln
insecure: false

jobservice:
max_job_workers: 10
max_job_duration_hours: 24
job_loggers:
- STD_OUTPUT
- FILE
logger_sweeper_duration: 1

notification:
webhook_job_max_retry: 3
webhook_job_http_client_timeout: 3

log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor

_version: ${HARBOR_VERSION}

proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- trivy

upload_purging:
enabled: true
age: 168h
interval: 24h
dryrun: false

cache:
enabled: true
expire_hours: 24
EOF2
ok "已生成 harbor.yml"
fi

# ---------- 6. 打印客户端接入方法(按模式不同) ----------
if [ "${DEPLOY_MODE}" = "http" ]; then
cat <<EOF2

[提示] 当前为 HTTP 模式,客户端节点如需 docker login/push/pull,
请把 insecure-registries 加入 /etc/docker/daemon.json 后重启 docker:
"insecure-registries": ["${HARBOR_HOSTNAME}", "${HARBOR_SERVER_IP}:${HTTP_PORT}"]
EOF2
elif [ "${DEPLOY_MODE}" = "https-lb" ]; then
cat <<EOF2

[提示] 当前为 LB 终止 TLS 模式:Harbor 本机仅监听 HTTP:${HTTP_PORT},由入口 LB 对外提供 HTTPS。
LB 配置要点:
1. 证书绑定在 LB 上的 ${HARBOR_HOSTNAME}
2. 转发到 ${HARBOR_SERVER_IP}:${HTTP_PORT},保留 Host 头
3. 添加请求头 X-Forwarded-Proto: https(否则 Harbor 生成的链接/跳转异常)
EOF2
else
cat <<EOF2

[提示] 当前为自签 HTTPS 模式,CA 证书: ${CERT_DIR}/ca.crt。
客户端需能解析 ${HARBOR_HOSTNAME}(/etc/hosts 加 "${HARBOR_SERVER_IP} ${HARBOR_HOSTNAME}" 或走 DNS)。
--- Docker 客户端节点(含本机) ---
mkdir -p /etc/docker/certs.d/${HARBOR_HOSTNAME}
cp ${CERT_DIR}/ca.crt ${CERT_DIR}/${HARBOR_HOSTNAME}.cert ${CERT_DIR}/${HARBOR_HOSTNAME}.key /etc/docker/certs.d/${HARBOR_HOSTNAME}/
systemctl restart docker
docker login ${HARBOR_HOSTNAME}
(若用 IP 访问,把上面目录名 ${HARBOR_HOSTNAME} 换成 ${HARBOR_SERVER_IP} 即可)
--- K8S 节点(containerd,kubeadm 默认) ---
mkdir -p /etc/containerd/certs.d/${HARBOR_HOSTNAME}
cp ${CERT_DIR}/ca.crt /etc/containerd/certs.d/${HARBOR_HOSTNAME}/
cat > /etc/containerd/certs.d/${HARBOR_HOSTNAME}/hosts.toml <<'TOML'
server = "https://${HARBOR_HOSTNAME}"

[host."https://${HARBOR_HOSTNAME}"]
capabilities = ["pull", "resolve"]
ca = "/etc/containerd/certs.d/${HARBOR_HOSTNAME}/ca.crt"
TOML
systemctl restart containerd
EOF2
fi

# ---------- 7. 执行安装(已在运行则跳过) ----------
if docker compose ps --status running --services 2>/dev/null | grep -qx core; then
ok "Harbor 已在运行,跳过安装。重装请执行: docker compose down && rm -f harbor.yml 后重跑本脚本"
else
echo ">>> 开始安装 Harbor v${HARBOR_VERSION} ..."
./install.sh || err "install.sh 执行失败,修复后重跑本脚本即可"
fi

case "${DEPLOY_MODE}" in
http) ACCESS_URL="http://<本机IP>:${HTTP_PORT}" ;;
https-lb) ACCESS_URL="https://${HARBOR_HOSTNAME} (经 LB 转发)" ;;
https) ACCESS_URL="https://${HARBOR_HOSTNAME} (或 https://${HARBOR_SERVER_IP})" ;;
esac

echo ""
echo "=============================================================="
echo " Harbor v${HARBOR_VERSION} 安装完成(模式: ${DEPLOY_MODE})"
echo " 访问地址: ${ACCESS_URL}"
echo " 登录账号: admin / ${ADMIN_PASSWORD} (仅首次生效)"
echo " 程序目录: ${INSTALL_DIR}"
echo " 数据目录: ${DATA_VOLUME}"
echo "=============================================================="
EOF

bash harbor_quick_install.sh
🛡️本站已安全运行2334天23时19分00秒
Bottom GIF
Top GIF