欢迎光临
我们一直在努力

从零到一:我在服务器上部署企业级镜像仓库 Harbor 的全过程记录

🚀 从零到一:我在服务器上部署企业级镜像仓库 Harbor 的全过程记录

一、 前言:为什么我需要一个私有镜像仓库? 🤔

在我的微服务项目 hx-health-cloud 的开发过程中,我遇到了一个经典的需求:我需要一个地方来统一、安全地管理我们团队构建的所有 Docker 镜像。直接使用公共的 Docker Hub 不仅有速率限制,更重要的是,将包含业务代码的镜像放在公网上,始终存在安全隐患。

经过一番调研,我决定放弃轻量级的 registry 方案,直接一步到位,选择云原生计算基金会 (CNCF, Cloud Native Computing Foundation) 的毕业项目——Harbor,来为我的测试环境搭建一个功能强大的企业级私有镜像仓库。

这篇文章,将完整记录我从一台全新的 Ubuntu 服务器开始,直到成功部署并运行 Harbor 的每一个步骤、每一个命令、甚至每一次深入源码的思考。

二、 准备阶段:兵马未动,粮草先行 🛠️

在开始“施工”之前,我先确保我的“地基”是稳固的。

  • 服务器就位 🖥️:我准备了一台运行 Ubuntu 22.04 LTS (Long Term Support, 长期支持) 的虚拟机,IP (Internet Protocol, 互联网协议) 地址为 192.168.31.73。这台机器满足 Harbor 的最低要求(2核/4G内存)。
  • SSH 登录 💻:我通过 ssh dgq@192.168.31.73 成功登录到服务器。系统提示我有 279 个更新可以应用,还有一个重要的提醒 *** System restart required ***。对于一个测试环境,我决定暂时忽略它们,专注于 Harbor 的部署。
  • 安装关键工具 jq 🔧:我知道 Harbor 的自动化安装脚本需要从 GitHub API (Application Programming Interface, 应用程序编程接口) 获取信息,而 jq 是一个解析 JSON (JavaScript Object Notation, JavaScript对象表示法) 的神器。我执行了以下命令来安装它:sudo apt update && sudo apt install -y jq

    终端输出显示,apt 更新了软件包列表,并成功安装了 jq 及其依赖 libjq1 和 libonig5。一切顺利!

  • 三、 核心步骤:自动化与配置的艺术 🎨

    第一步:【自动化】一键获取最新版 Harbor

    我不想手动去 GitHub 的 Release 页面翻找最新版本和下载链接。于是,我使用了下面这个非常酷的自动化脚本,它能帮我搞定一切。

    我直接在终端完整地复制、粘贴并执行了这段脚本:

    #!/bin/bash

    # — 脚本开始 —

    echo "🚀 正在查询 Harbor 最新稳定版本…"

    # 1. 使用 GitHub API 获取最新 release 的信息
    LATEST_RELEASE_URL=$(curl -s https://api.github.com/repos/goharbor/harbor/releases/latest)

    # 2. 使用 jq 解析出在线安装包 (online-installer) 的下载链接
    DOWNLOAD_URL=$(echo "$LATEST_RELEASE_URL" | jq -r '.assets[] | select(.name | contains("online-installer")) | .browser_download_url')

    # 3. 检查是否成功获取到 URL
    if [ -z "$DOWNLOAD_URL" ]; then
    echo "❌ 错误:无法自动获取最新的 Harbor 下载链接。请检查网络连接或手动访问 https://github.com/goharbor/harbor/releases"
    exit 1
    fi

    # 4. 从 URL 中提取文件名
    FILENAME=$(basename "$DOWNLOAD_URL")

    echo "✅ 找到最新版本文件: $FILENAME"
    echo "开始下载,请稍候…"

    # 5. 使用 wget 下载文件,并显示进度条
    wget -q –show-progress "$DOWNLOAD_URL"

    # 6. 检查下载是否成功
    if [ $? -ne 0 ]; then
    echo "❌ 错误:文件下载失败。"
    exit 1
    fi

    echo "✅ 下载完成,正在解压…"

    # 7. 解压下载的 tgz 文件
    tar xzvf "$FILENAME"

    # 8. 检查解压是否成功
    if [ $? -ne 0 ]; then
    echo "❌ 错误:文件解压失败。"
    exit 1
    fi

    echo "🎉 成功!Harbor 安装文件已准备就绪,位于 'harbor' 目录中。"
    echo "下一步:请进入 '
    harbor' 目录并配置 'harbor.yml' 文件。"

    # — 脚本结束 —

    终端的输出让我非常满意,它完美地执行了我的意图:

    🚀 正在查询 Harbor 最新稳定版本…
    ✅ 找到最新版本文件: harbor-online-installer-v2.14.0.tgz
    开始下载,请稍候…
    harbor-online-installer-v2.14.0.tgz 100%[===================>] 11.54K –.-KB/s in 0.02s
    ✅ 下载完成,正在解压…
    harbor/prepare
    harbor/LICENSE
    harbor/install.sh
    harbor/common.sh
    harbor/harbor.yml.tmpl
    🎉 成功!Harbor 安装文件已准备就绪,位于 'harbor' 目录中。

    太棒了!脚本自动帮我找到了最新的 v2.14.0 版本,并完成了下载和解压。我甚至都不需要知道版本号是多少!

    第二步:个性化配置 harbor.yml

    这是整个过程中唯一需要我手动“创作”的部分。

  • 进入 harbor 目录并创建配置文件:

    cd harbor
    cp harbor.yml.tmpl harbor.yml

  • 编辑配置文件:
    我习惯性地输入 vim harbor.yml,结果系统提示 Command 'vim' not found。这是一个小插曲,说明我的服务器是一个非常纯净的环境。系统友好地提示我可以用 sudo apt install vim 来安装。不过,为了不节外生枝,我选择了另一个预装的编辑器 nano:

    nano harbor.yml

  • 我的配置决策:
    在 nano 编辑器中,我进行了以下关键修改:

    • hostname: 我没有使用域名,因为这只是一个内部测试环境。我直接将其设置为我服务器的 IP 地址:192.168.31.73。
    • http.port: 为了避免与服务器上可能存在的其他服务(如 Nginx)冲突,我将默认的 80 端口改为了 81。
    • https: 我用 # 注释掉了整个 https 配置块。因为这是内部测试,暂时不需要配置复杂的 HTTPS (HyperText Transfer Protocol Secure, 安全超文本传输协议)。(注意:这在生产环境中是绝对不推荐的!)
    • harbor_admin_password: 我设置了一个简单的初始密码 Harbor12345。
    • database.password: 我也为数据库设置了一个密码 root123。
    • 其他配置(如 data_volume)我都保留了默认值。

    配置完成后,我使用 cat harbor.yml 命令检查了一遍,确保修改无误。

  • 第三步:执行安装,见证奇迹的时刻 ✨

    一切准备就绪,我以 sudo 权限运行了 Harbor 的安装脚本:

    sudo ./install.sh

    终端的输出就像一部精彩的戏剧,上演了 Harbor 的诞生过程:

  • [Step 0 & 1] 环境检查 ✅:脚本首先检查了 docker 和 docker-compose 是否存在。根据我的终端日志,它确认了我的环境版本,这对于问题排查至关重要。

    • Docker Version: 28.4.0
    • Docker Compose Version: v2.40.0

    这里有一个非常巧妙的技术细节。通过直接查看 common.sh 源码,我发现了 check_dockercompose 函数的真实逻辑。它设计得非常健壮:

  • 它会优先尝试检测 docker compose (V2) 命令。
  • 当它在我的系统中成功检测到 V2 版本后(输出了 v2.40.0),它会动态地将内部用于执行命令的变量,从 V1 的 docker-compose 修改为 V2 的 docker compose。
  • 如果 V2 不存在,它才会去检测 V1 命令。
  • 这意味着,尽管脚本的 install.sh 文件中可能有一个 V1 的默认值,但它在运行时,是真真正正地使用了我系统中的 V2 插件来完成所有后续操作。这确保了脚本对新旧环境的强大兼容性。

  • [Step 2 & 3] 环境与配置准备 ⚙️:脚本拉取了一个名为 goharbor/prepare 的工具镜像。这个镜像是 Harbor 安装的“瑞士军刀”,它读取我的 harbor.yml,然后动态生成了所有服务(Nginx, Core, Registry, DB…)所需的配置文件,以及最终的 docker-compose.yml。

    • 一个重要的警告出现了:WARNING:root:WARNING: HTTP protocol is insecure.。这正是我预料到的,因为它检测到我禁用了 HTTPS。对于测试环境,我可以接受这个风险。
  • [Step 4] 启动 Harbor 🚀:

    • 拉取镜像: 脚本开始从 Docker Hub 拉取 Harbor 运行所需的所有服务镜像。redis, registryctl, proxy, postgresql… 看着一个个 Pulled 完成,非常有成就感。
    • 启动容器: 镜像准备就绪后,脚本使用 docker compose 启动了所有服务。harbor-log, redis, harbor-db… 十个容器相继 Started。
  • 最终的礼炮 🎉:
    屏幕上打印出了那句最令人期待的话:

    ✔ —-Harbor has been installed and started successfully.—-

    成功了!整个过程自动化程度非常高,我需要做的只是修改一份配置文件。

  • 四、 验证与展望 🔭

    我现在可以通过浏览器访问 http://192.168.31.73:81,使用 admin 和我设置的密码 Harbor12345 登录我的私有镜像仓库了。

    接下来,我就可以为我的 hx-health-cloud 项目创建私有项目,并将 hx-auth, hx-gateway 等服务的镜像推送到这里,实现开发、测试流程的闭环。

    这次部署经历非常顺畅,Harbor 的自动化安装脚本做得非常出色。它再次证明了,选择一个优秀的、社区成熟的开源项目,能极大地提升我们的工作效率。


    总结与图表分析

    表格总结
    步骤核心任务使用的命令/工具关键输出/结果备注
    准备阶段 登录服务器 & 安装 jq ssh, sudo apt install -y jq ✅ jq 安装成功 jq 是自动化脚本的关键依赖
    第一步 自动下载并解压最新版 curl, jq, wget, tar ✅ harbor 目录及安装文件就绪 实现了版本解耦,无需手动查找
    第二步 个性化配置 cp, nano harbor.yml ✅ harbor.yml 配置完成 关键:修改 hostname 和密码
    第三步 执行安装 sudo ./install.sh ✅ 所有 Harbor 容器成功启动 脚本自动化了所有复杂操作
    验证阶段 访问 UI & 推送镜像 浏览器, docker login/push ✅ 成功登录并推送镜像 证明整个仓库功能正常
    Mermaid 流程图:Harbor 部署之路

    #mermaid-svg-BnJ8rn8CAu5J8T6k {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:14px;fill:#2C3E50;}#mermaid-svg-BnJ8rn8CAu5J8T6k .error-icon{fill:hsl(348.1481481481, 75.7009345794%, 46.9607843137%);}#mermaid-svg-BnJ8rn8CAu5J8T6k .error-text{fill:rgb(44.5981308413, 225.9018691588, 190.0887850466);stroke:rgb(44.5981308413, 225.9018691588, 190.0887850466);}#mermaid-svg-BnJ8rn8CAu5J8T6k .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-BnJ8rn8CAu5J8T6k .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-BnJ8rn8CAu5J8T6k .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-BnJ8rn8CAu5J8T6k .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-BnJ8rn8CAu5J8T6k .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-BnJ8rn8CAu5J8T6k .marker{fill:#7F8C8D;stroke:#7F8C8D;}#mermaid-svg-BnJ8rn8CAu5J8T6k .marker.cross{stroke:#7F8C8D;}#mermaid-svg-BnJ8rn8CAu5J8T6k svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:14px;}#mermaid-svg-BnJ8rn8CAu5J8T6k .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#fff;}#mermaid-svg-BnJ8rn8CAu5J8T6k .cluster-label text{fill:rgb(44.5981308413, 225.9018691588, 190.0887850466);}#mermaid-svg-BnJ8rn8CAu5J8T6k .cluster-label span{color:rgb(44.5981308413, 225.9018691588, 190.0887850466);}#mermaid-svg-BnJ8rn8CAu5J8T6k .label text,#mermaid-svg-BnJ8rn8CAu5J8T6k span{fill:#fff;color:#fff;}#mermaid-svg-BnJ8rn8CAu5J8T6k .node rect,#mermaid-svg-BnJ8rn8CAu5J8T6k .node circle,#mermaid-svg-BnJ8rn8CAu5J8T6k .node ellipse,#mermaid-svg-BnJ8rn8CAu5J8T6k .node polygon,#mermaid-svg-BnJ8rn8CAu5J8T6k .node path{fill:#1ABC9C;stroke:hsl(168.1481481481, 35.7009345794%, 31.9607843137%);stroke-width:1px;}#mermaid-svg-BnJ8rn8CAu5J8T6k .node .label{text-align:center;}#mermaid-svg-BnJ8rn8CAu5J8T6k .node.clickable{cursor:pointer;}#mermaid-svg-BnJ8rn8CAu5J8T6k .arrowheadPath{fill:undefined;}#mermaid-svg-BnJ8rn8CAu5J8T6k .edgePath .path{stroke:#7F8C8D;stroke-width:2.0px;}#mermaid-svg-BnJ8rn8CAu5J8T6k .flowchart-link{stroke:#7F8C8D;fill:none;}#mermaid-svg-BnJ8rn8CAu5J8T6k .edgeLabel{background-color:hsl(48.1481481481, 75.7009345794%, 41.9607843137%);text-align:center;}#mermaid-svg-BnJ8rn8CAu5J8T6k .edgeLabel rect{opacity:0.5;background-color:hsl(48.1481481481, 75.7009345794%, 41.9607843137%);fill:hsl(48.1481481481, 75.7009345794%, 41.9607843137%);}#mermaid-svg-BnJ8rn8CAu5J8T6k .cluster rect{fill:hsl(348.1481481481, 75.7009345794%, 46.9607843137%);stroke:hsl(348.1481481481, 35.7009345794%, 36.9607843137%);stroke-width:1px;}#mermaid-svg-BnJ8rn8CAu5J8T6k .cluster text{fill:rgb(44.5981308413, 225.9018691588, 190.0887850466);}#mermaid-svg-BnJ8rn8CAu5J8T6k .cluster span{color:rgb(44.5981308413, 225.9018691588, 190.0887850466);}#mermaid-svg-BnJ8rn8CAu5J8T6k div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(348.1481481481, 75.7009345794%, 46.9607843137%);border:1px solid undefined;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-BnJ8rn8CAu5J8T6k :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-BnJ8rn8CAu5J8T6k .start>*{fill:#58D68D!important;stroke:#28B463!important;stroke-width:2px!important;}#mermaid-svg-BnJ8rn8CAu5J8T6k .start span{fill:#58D68D!important;stroke:#28B463!important;stroke-width:2px!important;}#mermaid-svg-BnJ8rn8CAu5J8T6k .process>*{fill:#85C1E9!important;stroke:#3498DB!important;stroke-width:2px!important;}#mermaid-svg-BnJ8rn8CAu5J8T6k .process span{fill:#85C1E9!important;stroke:#3498DB!important;stroke-width:2px!important;}#mermaid-svg-BnJ8rn8CAu5J8T6k .decision>*{fill:#F39C12!important;stroke:#D35400!important;stroke-width:2px!important;}#mermaid-svg-BnJ8rn8CAu5J8T6k .decision span{fill:#F39C12!important;stroke:#D35400!important;stroke-width:2px!important;}#mermaid-svg-BnJ8rn8CAu5J8T6k .success>*{fill:#58D68D!important;stroke:#28B463!important;stroke-width:2px!important;}#mermaid-svg-BnJ8rn8CAu5J8T6k .success span{fill:#58D68D!important;stroke:#28B463!important;stroke-width:2px!important;}#mermaid-svg-BnJ8rn8CAu5J8T6k .failure>*{fill:#E74C3C!important;stroke:#C0392B!important;stroke-width:2px!important;color:white!important;}#mermaid-svg-BnJ8rn8CAu5J8T6k .failure span{fill:#E74C3C!important;stroke:#C0392B!important;stroke-width:2px!important;color:white!important;}开始: 准备服务器安装依赖 'jq'运行自动化脚本下载Harbor下载并解压成功?进入 'harbor' 目录配置 'harbor.yml' 文件运行 'install.sh' 脚本所有容器启动成功?通过浏览器访问UI登录并推送镜像进行验证部署成功 🎉检查网络或脚本错误检查Docker或配置错误

    Sequence Diagram: install.sh 脚本的内部工作流

    #mermaid-svg-vyvCqJpAfTBWzwPp {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-vyvCqJpAfTBWzwPp .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-vyvCqJpAfTBWzwPp .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-vyvCqJpAfTBWzwPp .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-vyvCqJpAfTBWzwPp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vyvCqJpAfTBWzwPp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vyvCqJpAfTBWzwPp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vyvCqJpAfTBWzwPp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vyvCqJpAfTBWzwPp .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-vyvCqJpAfTBWzwPp .marker.cross{stroke:#0b0b0b;}#mermaid-svg-vyvCqJpAfTBWzwPp svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vyvCqJpAfTBWzwPp .actor{stroke:#5DADE2;fill:#AED6F1;}#mermaid-svg-vyvCqJpAfTBWzwPp text.actor>tspan{fill:#333;stroke:none;}#mermaid-svg-vyvCqJpAfTBWzwPp .actor-line{stroke:grey;}#mermaid-svg-vyvCqJpAfTBWzwPp .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-vyvCqJpAfTBWzwPp .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-vyvCqJpAfTBWzwPp #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-vyvCqJpAfTBWzwPp .sequenceNumber{fill:#f4f4f4;}#mermaid-svg-vyvCqJpAfTBWzwPp #sequencenumber{fill:#333;}#mermaid-svg-vyvCqJpAfTBWzwPp #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-vyvCqJpAfTBWzwPp .messageText{fill:#333;stroke:#333;}#mermaid-svg-vyvCqJpAfTBWzwPp .labelBox{stroke:#5DADE2;fill:#AED6F1;}#mermaid-svg-vyvCqJpAfTBWzwPp .labelText,#mermaid-svg-vyvCqJpAfTBWzwPp .labelText>tspan{fill:#333;stroke:none;}#mermaid-svg-vyvCqJpAfTBWzwPp .loopText,#mermaid-svg-vyvCqJpAfTBWzwPp .loopText>tspan{fill:#333;stroke:none;}#mermaid-svg-vyvCqJpAfTBWzwPp .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:#5DADE2;fill:#5DADE2;}#mermaid-svg-vyvCqJpAfTBWzwPp .note{stroke:hsl(52.6829268293, 60%, 73.9215686275%);fill:#fff5ad;}#mermaid-svg-vyvCqJpAfTBWzwPp .noteText,#mermaid-svg-vyvCqJpAfTBWzwPp .noteText>tspan{fill:#333;stroke:none;}#mermaid-svg-vyvCqJpAfTBWzwPp .activation0{fill:hsl(-79.4117647059, 100%, 93.3333333333%);stroke:hsl(-79.4117647059, 100%, 83.3333333333%);}#mermaid-svg-vyvCqJpAfTBWzwPp .activation1{fill:hsl(-79.4117647059, 100%, 93.3333333333%);stroke:hsl(-79.4117647059, 100%, 83.3333333333%);}#mermaid-svg-vyvCqJpAfTBWzwPp .activation2{fill:hsl(-79.4117647059, 100%, 93.3333333333%);stroke:hsl(-79.4117647059, 100%, 83.3333333333%);}#mermaid-svg-vyvCqJpAfTBWzwPp .actorPopupMenu{position:absolute;}#mermaid-svg-vyvCqJpAfTBWzwPp .actorPopupMenuPanel{position:absolute;fill:#AED6F1;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-vyvCqJpAfTBWzwPp .actor-man line{stroke:#5DADE2;fill:#AED6F1;}#mermaid-svg-vyvCqJpAfTBWzwPp .actor-man circle,#mermaid-svg-vyvCqJpAfTBWzwPp line{stroke:#5DADE2;fill:#AED6F1;stroke-width:2px;}#mermaid-svg-vyvCqJpAfTBWzwPp :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}用户"安装脚本""goharbor/prepare""Docker Compose"sudo ./install.sh检查环境 (Docker, Compose)拉取并运行读取 harbor.yml, 生成所有配置文件返回生成的配置调用 'docker compose up -d'拉取所有服务镜像创建并启动所有容器返回启动成功信息显示 "Harbor installed successfully"用户"安装脚本""goharbor/prepare""Docker Compose"

    State Diagram: Harbor 服务的状态

    #mermaid-svg-Pez8C35d3TqnqIoS {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Pez8C35d3TqnqIoS .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-Pez8C35d3TqnqIoS .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-Pez8C35d3TqnqIoS .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Pez8C35d3TqnqIoS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Pez8C35d3TqnqIoS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Pez8C35d3TqnqIoS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Pez8C35d3TqnqIoS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Pez8C35d3TqnqIoS .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-Pez8C35d3TqnqIoS .marker.cross{stroke:#0b0b0b;}#mermaid-svg-Pez8C35d3TqnqIoS svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Pez8C35d3TqnqIoS defs #statediagram-barbEnd{fill:#5D6D7E;stroke:#5D6D7E;}#mermaid-svg-Pez8C35d3TqnqIoS g.stateGroup text{fill:hsl(40.5882352941, 60%, 83.3333333333%);stroke:none;font-size:10px;}#mermaid-svg-Pez8C35d3TqnqIoS g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-Pez8C35d3TqnqIoS g.stateGroup .state-title{font-weight:bolder;fill:#333;}#mermaid-svg-Pez8C35d3TqnqIoS g.stateGroup rect{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);}#mermaid-svg-Pez8C35d3TqnqIoS g.stateGroup line{stroke:#0b0b0b;stroke-width:1;}#mermaid-svg-Pez8C35d3TqnqIoS .transition{stroke:#5D6D7E;stroke-width:1;fill:none;}#mermaid-svg-Pez8C35d3TqnqIoS .stateGroup .composit{fill:#f4f4f4;border-bottom:1px;}#mermaid-svg-Pez8C35d3TqnqIoS .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-Pez8C35d3TqnqIoS .state-note{stroke:hsl(52.6829268293, 60%, 73.9215686275%);fill:#fff5ad;}#mermaid-svg-Pez8C35d3TqnqIoS .state-note text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-Pez8C35d3TqnqIoS .stateLabel .box{stroke:none;stroke-width:0;fill:#fff4dd;opacity:0.5;}#mermaid-svg-Pez8C35d3TqnqIoS .edgeLabel .label rect{fill:#fff4dd;opacity:0.5;}#mermaid-svg-Pez8C35d3TqnqIoS .edgeLabel .label text{fill:#333;}#mermaid-svg-Pez8C35d3TqnqIoS .label div .edgeLabel{color:#333;}#mermaid-svg-Pez8C35d3TqnqIoS .stateLabel text{fill:#333;font-size:10px;font-weight:bold;}#mermaid-svg-Pez8C35d3TqnqIoS .node circle.state-start{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-Pez8C35d3TqnqIoS .node .fork-join{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-Pez8C35d3TqnqIoS .node circle.state-end{fill:hsl(40.5882352941, 60%, 83.3333333333%);stroke:#f4f4f4;stroke-width:1.5;}#mermaid-svg-Pez8C35d3TqnqIoS .end-state-inner{fill:#f4f4f4;stroke-width:1.5;}#mermaid-svg-Pez8C35d3TqnqIoS .node rect{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-Pez8C35d3TqnqIoS .node polygon{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-Pez8C35d3TqnqIoS #statediagram-barbEnd{fill:#0b0b0b;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-cluster rect{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-Pez8C35d3TqnqIoS .cluster-label,#mermaid-svg-Pez8C35d3TqnqIoS .nodeLabel{color:#333;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-state .divider{stroke:hsl(40.5882352941, 60%, 83.3333333333%);}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-cluster.statediagram-cluster .inner{fill:#f4f4f4;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-cluster.statediagram-cluster-alt .inner{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-state rect.divider{stroke-dasharray:10,10;fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-Pez8C35d3TqnqIoS .note-edge{stroke-dasharray:5;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-note rect{fill:#fff5ad;stroke:hsl(52.6829268293, 60%, 73.9215686275%);stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-note rect{fill:#fff5ad;stroke:hsl(52.6829268293, 60%, 73.9215686275%);stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-note text{fill:#333;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram-note .nodeLabel{color:#333;}#mermaid-svg-Pez8C35d3TqnqIoS .statediagram .edgeLabel{color:red;}#mermaid-svg-Pez8C35d3TqnqIoS #dependencyStart,#mermaid-svg-Pez8C35d3TqnqIoS #dependencyEnd{fill:#0b0b0b;stroke:#0b0b0b;stroke-width:1;}#mermaid-svg-Pez8C35d3TqnqIoS :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}执行 install.sh所有容器启动成功执行 docker compose down执行 docker compose up日常使用卸载未安装安装中运行中已停止

    Class Diagram: Harbor 核心组件简化关系

    在这里插入图片描述

    Entity Relationship Diagram: Harbor 核心数据实体

    #mermaid-svg-KLEwK75SRIxgMCto {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-KLEwK75SRIxgMCto .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-KLEwK75SRIxgMCto .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-KLEwK75SRIxgMCto .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-KLEwK75SRIxgMCto .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KLEwK75SRIxgMCto .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KLEwK75SRIxgMCto .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KLEwK75SRIxgMCto .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KLEwK75SRIxgMCto .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-KLEwK75SRIxgMCto .marker.cross{stroke:#0b0b0b;}#mermaid-svg-KLEwK75SRIxgMCto svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KLEwK75SRIxgMCto .entityBox{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);}#mermaid-svg-KLEwK75SRIxgMCto .attributeBoxOdd{fill:#ffffff;stroke:hsl(40.5882352941, 60%, 83.3333333333%);}#mermaid-svg-KLEwK75SRIxgMCto .attributeBoxEven{fill:#f2f2f2;stroke:hsl(40.5882352941, 60%, 83.3333333333%);}#mermaid-svg-KLEwK75SRIxgMCto .relationshipLabelBox{fill:hsl(220.5882352941, 100%, 98.3333333333%);opacity:0.7;background-color:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-KLEwK75SRIxgMCto .relationshipLabelBox rect{opacity:0.5;}#mermaid-svg-KLEwK75SRIxgMCto .relationshipLine{stroke:#0b0b0b;}#mermaid-svg-KLEwK75SRIxgMCto :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}PROJECTintproject_idPKstringnameboolis_publicREPOSITORYintrepo_idPKintproject_idFKstringnameARTIFACTintartifact_idPKintrepo_idFKstringtagstringdigestUSER包含包含管理

    思维导图 (Markdown 格式)
    • Harbor 私有镜像仓库部署实战
      • 一、 准备阶段 🛠️
        • 服务器: Ubuntu 22.04 LTS, IP: 192.168.31.73
        • 登录: 通过 SSH 成功登录
        • 安装依赖: 使用 apt 安装 jq 工具
      • 二、 核心部署步骤 🎨
        • 1. 自动化下载 (第一步)
          • 方式: 使用包含 curl 和 jq 的 Shell 脚本
          • 目的: 自动获取 GitHub 最新稳定版的 online-installer
          • 结果: 成功下载并解压 harbor-online-installer-v2.14.0.tgz
        • 2. 个性化配置 (第二步)
          • 文件: harbor.yml (由 harbor.yml.tmpl 复制而来)
          • 编辑器: 使用 nano (因为 vim 未预装)
          • 关键修改:
            • hostname: 192.168.31.73 (使用 IP)
            • http.port: 81 (避免端口冲突)
            • https: 注释掉 (测试环境简化)
            • harbor_admin_password: Harbor12345
            • database.password: root123
        • 3. 执行安装 (第三步)
          • 命令: sudo ./install.sh
          • 过程:
            • 环境检查 (Docker 28.4.0, Docker Compose v2.40.0)
            • 配置准备 (使用 goharbor/prepare 镜像)
            • 启动服务 (拉取所有镜像并用 docker compose up 启动)
          • 结果: 终端显示 Harbor has been installed and started successfully
      • 三、 验证与后续 ✅
        • 访问: 浏览器打开 http://192.168.31.73:81
        • 登录: 用户名 admin,密码 Harbor12345
        • 后续操作:
          • 创建项目 (如 hx-health-cloud)
          • docker login
          • docker push 推送业务镜像
      • 四、 总结 🏁
        • 自动化脚本 极大简化了下载流程
        • harbor.yml 是唯一需要手动配置的核心
        • install.sh 封装了所有复杂性,实现了“一键部署”
    赞(0)
    未经允许不得转载:171主机测评 » 从零到一:我在服务器上部署企业级镜像仓库 Harbor 的全过程记录
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址