news 2026/9/16 17:24:24

Harbor企业级镜像仓库从零部署与排错实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Harbor企业级镜像仓库从零部署与排错实战

1. 为什么需要自己搭一个 Harbor?——从“Docker Hub 被限速”说起

Harbor 不是 Docker 的替代品,而是 Docker 生态里真正能让你把镜像“管起来”的那把锁。我第一次在客户现场踩坑,就是因为没提前搭 Harbor:开发团队用docker push往 Docker Hub 推一个 800MB 的 Spring Boot 镜像,推到 92% 卡住,重试三次全失败;运维同事查日志发现是 Docker Hub 对未认证账户的匿名推送限速到了 100KB/s,而他们用的是公司统一账号,但账号下绑了 17 个子团队,触发了速率熔断机制。这时候没人再关心“Docker 怎么安装”,所有人盯着屏幕问:“有没有办法让镜像不走公网?能不能本地存、本地验、本地删?”——答案就是 Harbor。

它不是个玩具,而是一套企业级镜像生命周期管理平台。你看到的“上传/下载镜像”,背后其实是四层能力在协同:存储层(底层用的是 Registry v2 协议)+ 权限层(项目级 RBAC,支持 LDAP/AD 同步)+ 安全层(镜像扫描、内容信任签名、漏洞报告)+ 治理层(镜像保留策略、GC 自动清理、审计日志归档)。很多教程只教“docker-compose up -d启起来就行”,结果上线三天就出事:某开发误删了生产环境的nginx:alpine镜像,因为 Harbor 默认项目权限是“开发可读写”,没人配过只读策略;还有一次,安全团队要求所有镜像必须通过 Clair 扫描后才能部署,但 Harbor 里没开扫描器开关,CI 流水线照常发布,最后被红队打穿。

所以这篇不是“Docker Desktop 上点几下就能跑的 Demo 教程”。我会带你从 CentOS 7.9 物理机开始,完整复现一个生产可用、权限可控、日志可溯、扫描可配的 Harbor 实例。重点讲清楚三个别人不说透的细节:

  • 为什么 Harbor 必须用 HTTPS?HTTP 模式下docker login会报x509: certificate signed by unknown authority,这不是证书问题,而是 Docker 客户端强制策略;
  • 为什么docker push harbor.example.com/project/app:v1.2里的域名必须和 Harbor 配置的hostname完全一致?少一个字符,push 就返回unauthorized: authentication required
  • 为什么用docker-compose启动后,harbor-core容器总在重启?大概率是/data目录权限不对,或者 PostgreSQL 初始化失败但日志被logrotate切走了。

你不需要会写 Go 或 Python,但得懂 Linux 文件权限、SSL 证书链、Docker daemon.json 配置逻辑。如果你正卡在“镜像上传 401”或“pull 报错 no basic auth credentials”,这篇文章会直接给你定位路径和修复命令。

2. 安装前必须确认的五件事——别跳过检查清单

Harbor 看似一键部署,实则对环境极其挑剔。我见过太多人卡在第 3 步,反复重装三次才发现是 SELinux 没关。下面这五件事,每一条都对应一个真实故障场景,必须逐项验证:

2.1 确认系统版本与内核参数(CentOS 7.9 是黄金组合)

Harbor 官方明确支持CentOS 7.6+ / Ubuntu 18.04+ / RHEL 7.6+,但实际生产中,CentOS 7.9 是最稳的选择。原因有三:

  • Docker CE 20.10.x 在 CentOS 7.9 上的 cgroup v1 兼容性最好,而 Harbor 的registry组件重度依赖 cgroup 内存限制;
  • firewalld规则模板在 7.9 中最全,harbor.yml里配置的80/443/4443端口能自动映射;
  • systemd版本 219 支持RestartSec=10这类精细重启控制,避免harbor-jobservice崩溃后无限重启拖垮宿主机。

提示:执行cat /etc/redhat-release && uname -r,输出必须是CentOS Linux release 7.9.20093.10.0-1160.el7.x86_64。如果内核低于3.10.0-1127,请先yum update -y && reboot,否则 Harbor 启动后registry容器会因memcg参数不识别而退出。

2.2 关闭 SELinux 与 firewalld(不是“建议”,是硬性要求)

Harbor 的clair(漏洞扫描器)和notary(内容信任服务)组件需要访问/data目录下的 socket 文件,而 SELinux 默认禁止跨域 socket 连接。我曾在一个金融客户环境里,SELinux 处于permissive模式,harbor-core日志里疯狂刷avc: denied { connectto } for pid=123 comm="core" path="/data/clair.sock",但容器就是不报错,直到用ausearch -m avc -ts recent才抓到这条拒绝日志。

正确操作只有两种:

  • 彻底关闭:setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
  • 或者临时放行(仅测试用):semanage port -a -t http_port_t -p tcp 8080(但 Harbor 默认不用 8080)

firewalld 同理。Harbor 依赖80(HTTP 重定向)、443(HTTPS 主服务)、4443(内部 API)三个端口。firewall-cmd --list-ports输出必须包含80/tcp 443/tcp 4443/tcp,否则docker login会超时。别信“用 iptables 替代”,Harbor 的prepare脚本会主动调用firewall-cmd,iptables 规则会被覆盖。

2.3 磁盘空间与挂载点规划(/data 目录必须独立)

Harbor 默认将所有数据(镜像、数据库、日志、证书)存放在/data目录。很多人直接用df -h看根分区还有 20GB 就开干,结果推入 5 个 Java 镜像后磁盘爆满,harbor-db容器因 PostgreSQL WAL 日志写满而崩溃。

真实需求测算如下:

  • 每个 500MB 的应用镜像,实际占用约 750MB(含 layer 压缩、metadata、scan 结果缓存);
  • PostgreSQL 数据库每万条镜像记录占 1.2GB;
  • 日志默认保留 7 天,每天约 80MB;
  • 所以 1TB 磁盘起步,且/data必须是独立挂载点(如xvdb1),不能是/下的子目录。

验证命令:

# 查看 /data 是否独立挂载 findmnt /data | grep -q "xvdb" && echo "OK" || echo "ERROR: /data not on separate disk" # 检查可用空间(需 > 500GB) df -h /data | awk 'NR==2 {print $4}' | grep -E '^[5-9][0-9]{2}G|[1-9][0-9]{3}G' >/dev/null && echo "Space OK" || echo "Insufficient space"

2.4 Docker 版本与 daemon.json 配置(20.10.17 是兼容阈值)

Harbor 2.5+ 要求 Docker Engine ≥ 20.10.10,但实测 20.10.17 最稳。低于此版本,docker pushregistry组件会因OCI manifest解析异常返回500 Internal Server Error

更重要的是daemon.json配置。很多教程忽略这点,导致docker login成功但push失败。关键参数只有两个:

  • "insecure-registries": ["harbor.example.com"]—— 如果用 HTTP 模式(不推荐),必须加此项;
  • "registry-mirrors": ["https://mirror.gcr.io"]—— 这个镜像源只影响docker pull,不影响 Harbor 上传,但能加速prepare脚本拉取基础镜像。

验证方法:

# 检查 Docker 版本 docker version --format '{{.Server.Version}}' | grep -E '^20\.10\.(1[7-9]|[2-9][0-9])$' >/dev/null && echo "Docker OK" || echo "Upgrade Docker" # 检查 daemon.json 是否存在且语法正确 jq empty /etc/docker/daemon.json 2>/dev/null && echo "daemon.json valid" || echo "daemon.json invalid"

2.5 DNS 与 hostname 解析(harbor.example.com 必须能 ping 通)

这是最隐蔽的坑。Harbor 安装脚本./install.sh会读取harbor.yml中的hostname字段,并生成对应证书。如果hostname设为harbor.example.com,但宿主机/etc/hosts里没配127.0.0.1 harbor.example.com,那么docker login harbor.example.com时,客户端会尝试解析 DNS,而内网 DNS 通常没有这条记录,最终超时。

正确做法分两步:

  1. 修改/etc/hostsecho "127.0.0.1 harbor.example.com" >> /etc/hosts
  2. harbor.yml中设置hostname: harbor.example.com(注意:不能写localhost127.0.0.1,Docker 客户端会拒绝连接)

验证命令:

# 必须返回 0 ping -c1 harbor.example.com &>/dev/null && echo "DNS OK" || echo "Fix /etc/hosts" # 检查 hostname 是否匹配 grep "^hostname:" harbor.yml | grep -q "harbor.example.com" && echo "Config OK" || echo "Edit harbor.yml"

3. 安装过程详解:从下载到启动的每一步意图

Harbor 安装本质是三阶段流水线:准备环境 → 生成配置 → 启动容器。网上很多教程把./install.sh当黑盒,但一旦失败,你连日志都找不到。下面我拆解每个命令背后的意图,告诉你该看什么日志、该改什么参数。

3.1 下载离线安装包并校验(为什么必须用 offline 包?)

Harbor 官方提供 online 和 offline 两种安装包。online 包只有 1.2MB,启动时动态拉取 1.2GB 的镜像;offline 包 1.2GB,自带全部镜像。生产环境必须用 offline 包,理由有二:

  • 网络不可靠:prepare脚本拉取goharbor/harbor-core:v2.5.3时若中断,不会重试,直接报错failed to pull image
  • 安全合规:金融客户要求所有镜像必须经内部 Nexus 代理,online 包的docker-compose.yml里写死image: goharbor/xxx,无法替换 registry 地址。

下载命令:

# 从官网下载(注意版本号) wget https://github.com/goharbor/harbor/releases/download/v2.5.3/harbor-offline-installer-v2.5.3.tgz # 校验 SHA256(官网页面有 checksum) echo "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 harbor-offline-installer-v2.5.3.tgz" | sha256sum -c

解压后目录结构必须包含:

  • harbor.yml.tmpl(模板文件)
  • install.sh(主安装脚本)
  • common.sh(环境检测函数)
  • prepare(核心配置生成器)

注意:不要mv harbor /opt/harbor,必须保持解压后目录名为harborinstall.sh里硬编码了./prepare路径,改名会导致command not found

3.2 配置 harbor.yml:七个必改参数与三个隐藏陷阱

harbor.yml是 Harbor 的心脏。官方模板有 200 行,但生产环境只需改 7 个参数。其余参数要么有默认值,要么留空即可。下面列出必须修改项,并解释每个值的业务含义:

参数示例值为什么必须改关联风险
hostnameharbor.example.comDocker 客户端认证域名,必须和docker login命令一致改成harbor.local会导致x509: certificate is valid for harbor.local, not harbor.example.com
http.port80HTTP 端口,用于重定向到 HTTPS设为8080时,docker login必须带端口harbor.example.com:8080,但 Docker 默认不支持带端口的 registry
https.port443HTTPS 主端口,所有 API 和 Web 访问走这里若设为8443,浏览器访问https://harbor.example.com:8443可打开,但docker login仍会连443
data_volume/data数据根目录,所有子目录(database、redis、jobservice)都在此下若指向/home/harbor/datachown -R 10000:10000 /home/harbor/data会失败,因为/home分区通常是noexec
database.passwordHarbor12345PostgreSQL 密码,长度必须 ≥ 8 且含大小写字母+数字密码含@符号会导致prepare脚本解析 YAML 失败,报yaml: line X: did not find expected key
harbor_admin_passwordHarbor12345Web 管理后台密码,同上规则密码太简单,登录后会被强制跳转到密码修改页,API 调用返回401 Unauthorized
clair.updater_interval12Clarity 漏洞库更新间隔(小时),设为0表示禁用设为1会导致每小时拉取 2GB 的 NVD 数据库,拖慢整个 Harbor 响应

三个隐藏陷阱:

  • 陷阱一:certificateprivate_key路径必须是绝对路径。模板里写./cert/harbor.crt,但prepare脚本会把它拼成/root/harbor/cert/harbor.crt,而证书实际在/data/cert/。正确写法是/data/cert/harbor.crt
  • 陷阱二:trivy.ignore_unfixed设为true时,扫描结果里不显示未修复漏洞。金融客户要求必须显示所有 CVE,所以必须设为false
  • 陷阱三:notification.endpoint如果配了企业微信 webhook,URL 必须以https://开头。配http://会导致harbor-core容器启动失败,日志报invalid URL scheme

3.3 执行 prepare 脚本:生成配置文件的底层逻辑

./prepare不是魔法,它只是个 Python 脚本(./common/prepare),作用是把harbor.yml里的参数注入到 12 个模板文件中。最关键的三个输出文件是:

  • common/config/registry/config.yml:Registry 服务配置,定义 storage backend(默认 filesystem)、auth(指向 core 服务)、middleware(blob cache);
  • common/config/core/app.conf:Core 服务配置,含数据库连接串、Redis 地址、Clair 扫描器地址;
  • docker-compose.yml:最终的容器编排文件,定义harbor-coreharbor-registryharbor-db等 8 个服务。

执行时加-f参数可指定 yml 文件:

./prepare -f harbor.yml

成功标志:

  • 控制台输出Generated configuration file: ./common/config/registry/config.yml等 12 行;
  • ls -l common/config/下所有文件时间戳都是当前时间;
  • docker-compose.ymlservices.harbor-core.environment.HARBOR_ADMIN_PASSWORD的值是加密后的字符串(不是明文)。

失败常见原因:

  • harbor.yml语法错误:yaml.parser.ParserError: while parsing a block mapping,用python -c "import yaml; print(yaml.load(open('harbor.yml'), Loader=yaml.FullLoader))"检查;
  • /data目录不存在或无写权限:OSError: [Errno 13] Permission denied: '/data/secret',执行mkdir -p /data && chown 10000:10000 /data
  • 证书文件路径错误:IOError: [Errno 2] No such file or directory: '/data/cert/harbor.crt',确认证书已放入/data/cert/且权限为644

3.4 启动 Harbor:docker-compose up -d 的真相

docker-compose up -d启动的是docker-compose.yml定义的 8 个服务。但它们的启动顺序有强依赖:

  1. harbor-db(PostgreSQL)→ 2.redis→ 3.harbor-registry→ 4.harbor-core→ 5.harbor-jobservice→ 6.harbor-portal→ 7.harbor-trivy→ 8.nginx

docker-compose本身不保证顺序,Harbor 用healthcheck解决:每个服务的docker-compose.yml里都有healthcheck.test字段,例如harbor-core的健康检查是curl -f http://localhost:8080/api/v2.0/ping || exit 1。只有前一个服务健康,后一个才启动。

启动后验证命令:

# 查看所有容器状态(必须全是 Up) docker-compose ps | awk 'NR>1 {print $1,$4}' | grep -v "Up" # 检查 harbor-core 是否监听 8080 docker exec harbor-core ss -tlnp | grep ":8080" # 检查 nginx 是否转发 443 到 8080 docker exec nginx ss -tlnp | grep ":443"

如果harbor-core一直 restarting,看日志:

docker logs harbor-core 2>&1 | tail -20

高频错误:

  • failed to connect to database: dial tcp 172.19.0.2:5432: connect: connection refusedharbor-db没起来,查docker logs harbor-db
  • failed to initialize database: pq: password authentication failed for user "harbor"harbor.ymldatabase.passwordharbor_db_password不一致;
  • failed to create table: pq: relation "project" does not exist→ PostgreSQL 数据库初始化失败,删掉/data/database重来。

4. Docker 上传与下载镜像:从 login 到 push 的全流程实操

安装完成只是起点。真正的价值在于让开发能顺畅地pushpull。这一节我用一个真实 Spring Boot 应用为例,从代码打包到镜像上传,全程演示,并标注每个命令背后的网络请求和权限校验点。

4.1 准备测试镜像:构建一个带标签的 Spring Boot 镜像

假设你有一个 Maven 项目,pom.xml里已配好spring-boot-maven-plugin。构建命令:

# 打包成 fat jar mvn clean package -DskipTests # 构建 Docker 镜像(注意:tag 必须含 Harbor 域名) docker build -t harbor.example.com/library/springboot-demo:v1.0 . # Dockerfile 内容(关键点:FROM 必须用 public 镜像,不能用 private registry) FROM openjdk:11-jre-slim VOLUME /tmp ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

提示:docker build-t参数的格式必须是harbor.example.com/项目名/镜像名:标签harbor.example.com是 registry 地址,library是 Harbor 里的项目名(需提前在 Web 界面创建),springboot-demo是镜像名,v1.0是标签。少任何一部分,push都会失败。

4.2 Docker login:认证流程的三次握手

docker login不是简单发个 token,而是标准的 Docker Registry V2 认证协议:

  1. 客户端向https://harbor.example.com/service/token?account=admin&service=harbor-registry发 GET 请求;
  2. Harbor 返回 JWT token 和 realm(认证域);
  3. 客户端用该 token 作为 Bearer Auth,向https://harbor.example.com/v2/发 HEAD 请求验证权限。

执行命令:

docker login harbor.example.com -u admin -p Harbor12345

成功标志:

  • 输出Login Succeeded
  • ~/.docker/config.json里新增"harbor.example.com": {"auth": "YWRtaW46SGFyYm9yMTIzNDU="}(base64 编码的admin:Harbor12345);
  • docker info | grep -A5 "Insecure Registries"显示harbor.example.com(如果用了 HTTP 模式)。

失败排查:

  • Error response from daemon: Get https://harbor.example.com/v2/: x509: certificate signed by unknown authority→ 客户端没信任 Harbor 的 CA 证书。解决:把/data/cert/harbor.crt复制到/etc/docker/certs.d/harbor.example.com/ca.crt,然后systemctl restart docker
  • Error response from daemon: Get https://harbor.example.com/v2/: unauthorized: authentication required→ 用户密码错,或项目library的成员里没加admin用户(Web 界面检查)。

4.3 Push 镜像:四步校验与失败定位

docker push是最易出错的环节。它实际执行四步校验:

  1. Registry 可达性校验curl -I https://harbor.example.com/v2/,返回200 OK
  2. 项目存在性校验curl -X GET https://harbor.example.com/api/v2.0/projects/library,返回200
  3. 用户权限校验curl -X GET https://harbor.example.com/api/v2.0/projects/library/members,检查admin是否在role_id: 1(项目管理员)列表中;
  4. Layer 上传校验:对每个 layer 发POST /v2/library/springboot-demo/blobs/uploads/,返回202 Accepted

执行命令:

docker push harbor.example.com/library/springboot-demo:v1.0

进度条显示The push refers to repository [harbor.example.com/library/springboot-demo]后,会依次上传layerconfigmanifest。如果卡在某个 layer,看日志:

# 在 Harbor 宿主机上实时监控 registry 日志 docker logs -f harbor-registry 2>&1 | grep -E "(PUSH|Blob|manifest)"

高频错误:

  • denied: requested access to the resource is denied→ 用户没library项目的Developer或更高权限;
  • unauthorized: authentication requireddocker login的 token 过期(默认 24 小时),重新docker login
  • received unexpected HTTP status: 500 Internal Server Errorharbor-registry存储层失败,检查/data/registry目录权限是否为10000:10000

4.4 Pull 镜像:从 Harbor 下载到本地的完整链路

docker pull比 push 简单,但仍有陷阱。命令:

# 先登出其他 registry,避免 credential 冲突 docker logout # 登录 Harbor docker login harbor.example.com -u admin -p Harbor12345 # 拉取镜像 docker pull harbor.example.com/library/springboot-demo:v1.0

拉取过程分三步:

  1. 获取 manifest:GET /v2/library/springboot-demo/manifests/v1.0,返回 JSON 描述所有 layer;
  2. 下载 config:GET /v2/library/springboot-demo/blobs/sha256:xxx
  3. 下载 layers:并发GET /v2/library/springboot-demo/blobs/sha256:yyy

验证是否成功:

# 查看本地镜像 docker images | grep springboot-demo # 运行测试 docker run -d -p 8080:8080 harbor.example.com/library/springboot-demo:v1.0 curl http://localhost:8080/actuator/health

注意:docker pull时,如果本地已有同名镜像(如springboot-demo:v1.0),它不会覆盖,而是创建新镜像 ID。要确保用harbor.example.com/前缀,否则会从 Docker Hub 拉取。

5. 常见问题与排查技巧实录:那些文档里不会写的坑

Harbor 的报错信息向来以“优雅的模糊”著称。下面是我三年运维中整理的 7 个高频问题,每个都附带 root cause、日志定位命令和一行修复命令。

5.1 问题:harbor-core 容器反复重启,日志显示failed to connect to redis

现象docker-compose ps显示harbor-core状态为Restartingdocker logs harbor-core最后一行是failed to connect to redis: dial tcp 172.19.0.3:6379: connect: connection refused

Root Causeharbor-redis容器启动失败,但docker-compose ps里状态还是Up(因为 healthcheck 没配)。真实原因是 Redis 配置内存不足,/data/redis目录权限不对,或redis.confmaxmemory设太高。

日志定位

# 查看 redis 容器日志 docker logs harbor-redis # 如果输出为空,说明容器根本没启动 docker inspect harbor-redis | grep -A5 "Status"

修复命令

# 删除旧数据(谨慎!) rm -rf /data/redis # 重启 redis docker-compose restart harbor-redis # 等 30 秒后检查 docker exec harbor-redis redis-cli ping # 应返回 PONG

5.2 问题:Web 界面能打开,但登录后 404,或点击“Projects”空白

现象:浏览器访问https://harbor.example.com显示登录页,输入 admin 密码后跳转到https://harbor.example.com/harbor/projects,页面空白,F12 看 Network 标签页,/api/v2.0/projects返回401 Unauthorized

Root Causeharbor-core服务的 JWT token 签名密钥不一致。harbor.ymlsecretkey_path默认是/data,但prepare脚本生成的密钥文件在/data/secret/下,而容器里挂载的是/data,导致core读不到密钥。

日志定位

# 查看 core 日志中的 token 错误 docker logs harbor-core 2>&1 | grep -i "token" | tail -5

修复命令

# 重建 secret 目录 mkdir -p /data/secret chown 10000:10000 /data/secret # 重新运行 prepare ./prepare -f harbor.yml # 重启 docker-compose down && docker-compose up -d

5.3 问题:docker push 时卡在 “waiting for layer upload”,数小时不动

现象docker push harbor.example.com/library/app:v1后,进度条停在waiting for layer uploaddocker logs harbor-registry无新日志。

Root Cause:Nginx 反向代理超时。Harbor 的nginx.confproxy_read_timeout默认 600 秒(10 分钟),但大镜像上传可能超时。Nginx 先断开连接,registry还在等数据,造成僵死。

日志定位

# 查看 nginx 错误日志 docker logs harbor-nginx 2>&1 | grep -i "timeout"

修复命令

# 修改 nginx 配置(在宿主机上) sed -i 's/proxy_read_timeout 600;/proxy_read_timeout 3600;/' /compose_location/nginx.conf # 重启 nginx docker-compose restart harbor-nginx

5.4 问题:Clair 扫描器一直显示 “Pending”,never start

现象:Web 界面点击镜像的 “Scan” 按钮,状态变成 “Pending”,10 分钟后还是 Pending,docker logs harbor-trivy无输出。

Root Cause:Trivy 数据库初始化失败。harbor.ymltrivy.skip_update设为true时,Trivy 不会下载漏洞库,但harbor-core仍会发扫描请求,导致 pending。

日志定位

# 查看 trivy 日志 docker logs harbor-trivy # 如果输出 “DB schema migration failed”,说明数据库损坏

修复命令

# 清空 trivy 数据 rm -rf /data/trivy # 设置 skip_update 为 false(首次启动必须下载) sed -i 's/skip_update: true/skip_update: false/' harbor.yml # 重新 prepare ./prepare -f harbor.yml # 重启 docker-compose restart harbor-trivy

5.5 问题:上传镜像后,Web 界面看不到,但 docker pull 能成功

现象docker push返回Pusheddocker pull成功,但 Harbor Web 界面的library项目里没有这个镜像。

Root Cause:项目设置了“机器人账户”(Robot Account),但docker login用的是admin用户,而admin不在该项目的成员列表中。Harbor 的权限模型是:项目级权限 > 用户全局权限

日志定位

# 查看 core 日志中的权限拒绝 docker logs harbor-core 2>&1 | grep -i "permission denied" | tail -3

修复命令

# 在 Web 界面操作:Projects → library → Members → + Add Member → User: admin → Role: Project Admin # 或用 API(需 token) curl -X POST "https://harbor.example.com/api/v2.0/projects/1/members" \ -H "Authorization: Basic $(echo -n 'admin:Harbor12345' | base64)" \ -H "Content-Type: application/json" \ -d '{"member_user":{"username":"admin"},"role_id":1}'

5.6 问题:harbor-db 容器启动失败,日志显示 “FATAL: could not open relation mapping file”

现象docker-compose ps显示harbor-db状态为Exit 1docker logs harbor-db输出FATAL: could not open relation mapping file "global/pg_filenode.map"

Root Cause:PostgreSQL 数据目录损坏。常见于强制docker kill或宿主机断电后,WAL 日志未刷盘。

日志定位

# 查看详细错误 docker logs harbor-db 2>&1 | head -20

修复命令

# 备份旧数据(重要!) cp -r /data/database /data/database.backup # 初始化新数据库 docker run -it --rm -v /data/database:/var/lib/postgresql/data gosu postgres postgres --initdb # 重启 docker-compose restart harbor-db

5.7 问题:docker login 报错 “Error saving credentials: error storing credentials”

现象docker login harbor.example.com

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 17:14:04

如何精简 Windows 11 官方镜像:tiny11builder 实操

如何精简 Windows 11 官方镜像:tiny11builder 实操 【免费下载链接】tiny11builder Scripts to build a trimmed-down Windows 11 image. 项目地址: https://gitcode.com/GitHub_Trending/ti/tiny11builder tiny11builder 是一套 PowerShell 脚本集&#xff…

作者头像 李华
网站建设 2026/9/16 17:12:57

Django视频点播网站搭建:从ORM建模到HLS播放与Nginx部署

简介:一套基于Django框架开发的视频点播网站完整源码,面向计算机、数学、电子信息等专业学生,适合作为课程设计、期末大作业或毕业设计参考项目。项目已实现视频播放、收藏、后台管理等功能模块,代码结构清晰,可直接下…

作者头像 李华
网站建设 2026/9/16 17:11:00

微信快递小程序源码全解析:ThinkPHP后端与部署实战

简介:2024最新版快递小程序源码是一套完整可运营的微信快递服务项目,后端基于ThinkPHP(PHP)框架构建,前端为微信小程序,覆盖查件、寄件下单、物流跟踪等功能,并兼顾数据加密与隐私保护&#xff…

作者头像 李华