跳过正文
  1. 博客文章/

企业级 Nexus3 制品仓库平台部署与运维完整指南

·6475 字·31 分钟·
Docker DevOps Nexus3 Docker Artifact-Repository Devops Package-Management
Zayn
作者
Zayn
专注 Kubernetes、CI/CD、可观测性等云原生技术栈,记录生产环境中的实战经验与踩坑复盘。
目录

Nexus3 是世界领先的企业级制品仓库管理平台,为现代 DevOps 工具链提供统一的制品管理解决方案。本指南将从基础部署到企业级配置,全面介绍 Nexus3 的部署、配置、管理和运维最佳实践。

Nexus3 平台简介
#

什么是 Nexus3
#

Nexus Repository Manager 3 是由 Sonatype 公司开发的下一代制品仓库管理平台,作为 DevOps 工具链的核心组件,为软件开发生命周期提供统一的制品管理能力。

核心特性
#

  • 统一制品管理:支持 20+ 种包格式的统一管理
  • 高性能架构:基于现代化架构设计,支持大规模并发访问
  • 企业级安全:细粒度权限控制、LDAP 集成、漏洞扫描
  • 智能代理:缓存外部仓库,提供离线访问能力
  • REST API:完整的 API 支持,便于自动化集成
  • 可扩展性:支持集群部署和水平扩展

支持的制品格式
#

类别格式用途
Java 生态Maven, GradleJava 项目依赖管理
前端生态npm, Bower, NuGet前端包管理
容器技术Docker, Helm容器镜像和 K8s 应用
系统包Yum, APT, Conan操作系统包管理
语言包PyPI, RubyGems, Go编程语言包管理
其他格式Raw, Git LFS, R通用文件和特殊格式

应用场景
#

  • DevOps 流水线:CI/CD 过程中的制品存储和分发
  • 依赖管理:统一管理项目依赖,减少外部风险
  • 版本控制:制品版本管理和发布控制
  • 安全合规:制品安全扫描和合规性检查
  • 成本优化:减少外网带宽消耗,提高下载速度

架构设计
#

单机架构
#

flowchart TB
    subgraph Nexus3[Nexus3 单机部署]
        A[Web UI / REST API / Repository]
        B[Repository Manager Core]
        C[Security / Tasks / Capabilities / Logs]
        D[OrientDB / Blob Store / Config]
    end

高可用架构
#

flowchart TB
    LB[Load Balancer]

    N1[Nexus3 Node 1]
    N2[Nexus3 Node 2]
    N3[Nexus3 Node 3]

    LB --> N1
    LB --> N2
    LB --> N3

    N1 -.->|Shared Storage| S1
    N2 -.->|Shared Storage| S1
    N3 -.->|Shared Storage| S1

    subgraph SharedStorage[Shared Storage]
        S1[PostgreSQL / Blob Store / NFS]
    end

仓库类型详解
#

Nexus3 支持三种不同类型的仓库,每种类型都有其特定的用途和优势:

1. Hosted 仓库(托管仓库)
#

用途: 存储企业内部开发的制品和第三方上传的包 特点:

  • 完全由企业自主管理
  • 可以上传、删除、修改制品
  • 适合存储内部开发的组件和库

使用场景:

  • 企业内部开发的 JAR 包、Docker 镜像
  • 第三方供应商提供的私有组件
  • 需要定制化的开源组件

2. Proxy 仓库(代理仓库)
#

用途: 代理外部公共仓库,提供缓存和加速功能 工作原理:

  1. 客户端请求依赖包
  2. 如果本地缓存存在,直接返回
  3. 如果本地不存在,从远程仓库下载并缓存
  4. 后续相同请求直接从缓存返回

代理仓库工作原理

优势:

  • 提高下载速度
  • 减少外网带宽消耗
  • 提供离线访问能力
  • 统一管理外部依赖

3. Group 仓库(组合仓库)
#

用途: 将多个仓库组合成一个统一的访问入口 特点:

  • 可以包含 hosted、proxy、group 类型的仓库
  • 支持优先级设置
  • 提供统一的访问地址

重要提示: Group 仓库采用自上而下的匹配策略,一旦找到匹配的制品就停止搜索。因此,仓库的排序非常重要:

Group 仓库优先级示例

在上图示例中,如果 customaliyun 仓库都包含 centos:7 镜像,客户端拉取时会优先获取 custom 仓库中的版本。

环境准备
#

系统要求
#

硬件要求
#

环境类型CPU内存存储网络
开发环境4 核8GB100GB1Gbps
测试环境8 核16GB500GB1Gbps
生产环境16 核32GB+2TB+10Gbps
大型企业32 核64GB+10TB+10Gbps

软件要求
#

组件最低版本推荐版本说明
操作系统CentOS 7.6CentOS 8+ / Ubuntu 20.04+64位系统
Docker19.03.020.10.0+容器运行时
Docker Compose1.25.01.29.0+容器编排工具
JavaOpenJDK 8OpenJDK 11+Nexus3 运行环境

网络端口规划
#

端口协议服务说明
8081TCPWeb UI管理界面和 REST API
8082TCPDocker PullDocker 镜像拉取
8083TCPDocker PushDocker 镜像推送
8084-8090TCPCustom Repos自定义仓库端口
5432TCPPostgreSQL外部数据库(可选)

环境检查脚本
#

cat > check-nexus-env.sh << 'EOF'
#!/bin/bash

echo "=== Nexus3 环境检查脚本 ==="
echo "检查时间: $(date)"
echo

# 检查操作系统
echo "=== 系统信息 ==="
cat /etc/redhat-release 2>/dev/null || lsb_release -a 2>/dev/null
uname -a
echo

# 检查内存
echo "=== 内存信息 ==="
free -h
TOTAL_MEM=$(free -m | awk 'NR==2{printf "%.0f", $2}')
if [ $TOTAL_MEM -lt 8192 ]; then
    echo "⚠ 警告: 内存不足 8GB,可能影响 Nexus3 性能"
else
    echo "✓ 内存充足"
fi
echo

# 检查磁盘空间
echo "=== 磁盘空间 ==="
df -h
DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $DISK_USAGE -gt 80 ]; then
    echo "⚠ 警告: 磁盘使用率超过 80%"
else
    echo "✓ 磁盘空间充足"
fi
echo

# 检查 Docker
echo "=== Docker 环境检查 ==="
if command -v docker >/dev/null 2>&1; then
    docker --version
    echo "✓ Docker 已安装"

    if systemctl is-active --quiet docker; then
        echo "✓ Docker 服务运行正常"
    else
        echo "✗ Docker 服务未运行"
    fi
else
    echo "✗ Docker 未安装"
fi
echo

# 检查 Docker Compose
echo "=== Docker Compose 检查 ==="
if command -v docker-compose >/dev/null 2>&1; then
    docker-compose --version
    echo "✓ Docker Compose 已安装"
else
    echo "✗ Docker Compose 未安装"
fi
echo

# 检查网络端口
echo "=== 端口检查 ==="
for port in 8081 8082 8083; do
    if netstat -tlnp | grep :$port >/dev/null 2>&1; then
        echo "⚠ 端口 $port 已被占用"
        netstat -tlnp | grep :$port
    else
        echo "✓ 端口 $port 可用"
    fi
done
echo

# 检查 Java 环境
echo "=== Java 环境检查 ==="
if command -v java >/dev/null 2>&1; then
    java -version
    echo "✓ Java 已安装"
else
    echo "ℹ Java 未安装(Docker 部署不需要)"
fi
echo

echo "=== 环境检查完成 ==="
EOF

chmod +x check-nexus-env.sh
./check-nexus-env.sh

存储规划
#

LVM 存储配置(推荐)
#

# 创建 LVM 存储配置脚本
cat > setup-nexus-storage.sh << 'EOF'
#!/bin/bash

DEVICE="/dev/sdb"  # 修改为实际设备
VG_NAME="nexus-vg"
LV_NAME="nexus-lv"
MOUNT_POINT="/data/nexus3"
SIZE="500G"  # 根据需求调整

echo "=== Nexus3 存储配置脚本 ==="
echo "设备: $DEVICE"
echo "挂载点: $MOUNT_POINT"
echo "大小: $SIZE"

read -p "确认继续?(y/N): " confirm
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
    echo "操作已取消"
    exit 0
fi

# 创建物理卷
echo "创建物理卷..."
pvcreate $DEVICE

# 创建卷组
echo "创建卷组..."
vgcreate $VG_NAME $DEVICE

# 创建逻辑卷
echo "创建逻辑卷..."
lvcreate -L $SIZE -n $LV_NAME $VG_NAME

# 格式化文件系统
echo "格式化文件系统..."
mkfs.xfs /dev/$VG_NAME/$LV_NAME

# 创建挂载点
echo "创建挂载点..."
mkdir -p $MOUNT_POINT

# 挂载文件系统
echo "挂载文件系统..."
mount /dev/$VG_NAME/$LV_NAME $MOUNT_POINT

# 添加到 fstab
echo "配置开机自动挂载..."
echo "/dev/$VG_NAME/$LV_NAME $MOUNT_POINT xfs defaults 0 0" >> /etc/fstab

# 设置权限
echo "设置目录权限..."
chown -R 200:200 $MOUNT_POINT
chmod 755 $MOUNT_POINT

echo "✓ 存储配置完成"
echo "挂载点: $MOUNT_POINT"
echo "可用空间: $(df -h $MOUNT_POINT | awk 'NR==2 {print $4}')"
EOF

chmod +x setup-nexus-storage.sh

网络和防火墙配置
#

# 防火墙配置脚本
cat > setup-nexus-firewall.sh << 'EOF'
#!/bin/bash

echo "=== Nexus3 防火墙配置 ==="

# 检查防火墙状态
if systemctl is-active --quiet firewalld; then
    echo "配置防火墙规则..."

    # 开放 Nexus3 端口
    firewall-cmd --permanent --add-port=8081/tcp  # Web UI
    firewall-cmd --permanent --add-port=8082/tcp  # Docker Pull
    firewall-cmd --permanent --add-port=8083/tcp  # Docker Push
    firewall-cmd --permanent --add-port=8084-8090/tcp  # 自定义端口

    # 重新加载防火墙
    firewall-cmd --reload

    echo "✓ 防火墙配置完成"
    firewall-cmd --list-ports
else
    echo "防火墙未启用"
fi

# SELinux 配置
if getenforce | grep -q "Enforcing"; then
    echo "配置 SELinux..."
    setsebool -P container_manage_cgroup on
    echo "✓ SELinux 配置完成"
fi

echo "=== 网络配置完成 ==="
EOF

chmod +x setup-nexus-firewall.sh
./setup-nexus-firewall.sh

Nexus3 部署实施
#

方案一:Docker 单机部署
#

步骤 1:创建项目目录
#

# 创建项目目录结构
mkdir -p /data/nexus3/{data,logs,backup,config}
cd /data/nexus3

# 设置目录权限(Nexus3 容器内使用 UID 200)
chown -R 200:200 /data/nexus3/data
chmod -R 755 /data/nexus3

# 设置 SELinux 上下文(如果启用)
if getenforce | grep -q "Enforcing"; then
    setsebool -P container_manage_cgroup on
    chcon -Rt svirt_sandbox_file_t /data/nexus3/data
fi

步骤 2:基础 Docker 部署
#

# 基础部署命令
docker run -d \
  --name nexus3 \
  --restart unless-stopped \
  --ulimit nofile=65536:65536 \
  -p 8081:8081 \
  -p 8082:8082 \
  -p 8083:8083 \
  -e INSTALL4J_ADD_VM_PARAMS="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=6g -Djava.util.prefs.userRoot=/nexus-data/javaprefs" \
  -v /etc/localtime:/etc/localtime:ro \
  -v /data/nexus3/data:/nexus-data \
  sonatype/nexus3:3.41.1

步骤 3:Docker Compose 部署(推荐)
#

cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  nexus3:
    image: sonatype/nexus3:3.41.1
    container_name: nexus3
    restart: unless-stopped
    hostname: nexus.your-domain.com

    ports:
      - "8081:8081"
      - "8082:8082"
      - "8083:8083"

    volumes:
      - ./data:/nexus-data
      - ./logs:/opt/sonatype/nexus/log
      - /etc/localtime:/etc/localtime:ro

    environment:
      - NEXUS_SECURITY_RANDOMPASSWORD=false
      - INSTALL4J_ADD_VM_PARAMS=-Xms4g -Xmx4g -XX:MaxDirectMemorySize=6g -Djava.util.prefs.userRoot=/nexus-data/javaprefs

    ulimits:
      nofile:
        soft: 65536
        hard: 65536

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8081/service/rest/v1/status"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 120s

networks:
  default:
    name: nexus-network
EOF

步骤 4:生产环境配置
#

cat > docker-compose.prod.yml << 'EOF'
version: '3.8'

services:
  nexus3:
    image: sonatype/nexus3:3.41.1
    container_name: nexus3-prod
    restart: unless-stopped
    hostname: nexus.company.com

    ports:
      - "8081:8081"
      - "8082:8082"
      - "8083:8083"
      - "8084:8084"  # 额外端口
      - "8085:8085"  # 额外端口

    volumes:
      - ./data:/nexus-data
      - ./logs:/opt/sonatype/nexus/log
      - ./backup:/backup
      - /etc/localtime:/etc/localtime:ro

    environment:
      - NEXUS_SECURITY_RANDOMPASSWORD=false
      - INSTALL4J_ADD_VM_PARAMS=-server -Xms8g -Xmx8g -XX:MaxDirectMemorySize=12g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UseStringDeduplication -Djava.util.prefs.userRoot=/nexus-data/javaprefs -Djava.net.preferIPv4Stack=true

    ulimits:
      nofile:
        soft: 65536
        hard: 65536
      memlock:
        soft: -1
        hard: -1

    deploy:
      resources:
        limits:
          memory: 16G
          cpus: '8'
        reservations:
          memory: 8G
          cpus: '4'

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8081/service/rest/v1/status"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 300s

    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"

networks:
  default:
    name: nexus-network
    driver: bridge
EOF

步骤 5:启动服务
#

# 开发环境启动
docker-compose up -d

# 生产环境启动
docker-compose -f docker-compose.prod.yml up -d

# 查看启动日志
docker-compose logs -f nexus3

# 等待服务完全启动(通常需要 3-5 分钟)
echo "等待 Nexus3 启动..."
timeout 300 bash -c 'until curl -f http://localhost:8081/service/rest/v1/status; do sleep 10; done'

JVM 参数说明

  • -Xms4g -Xmx4g: 堆内存大小(根据服务器配置调整)
  • -XX:MaxDirectMemorySize=6g: 直接内存大小
  • -XX:+UseG1GC: 使用 G1 垃圾收集器
  • -XX:MaxGCPauseMillis=200: GC 暂停时间目标
  • -XX:+UseStringDeduplication: 字符串去重优化

第三步:验证部署
#

检查容器状态
#

# 查看容器运行状态
docker ps | grep nexus3

# 查看容器日志
docker logs -f nexus3

# 检查端口监听
netstat -tlnp | grep -E "8081|8082|8083"

等待服务启动
#

Nexus3 首次启动需要较长时间(通常 2-5 分钟),请耐心等待:

# 监控启动日志,看到以下信息表示启动成功
docker logs -f nexus3 | grep "Started Sonatype Nexus"

获取初始密码
#

# 查看初始管理员密码
cat /application/nexus3/data/admin.password

# 或者在容器内查看
docker exec nexus3 cat /nexus-data/admin.password

初始化配置
#

获取初始管理员密码
#

# 等待 Nexus3 完全启动
echo "等待 Nexus3 启动完成..."
timeout 300 bash -c 'until docker exec nexus3 test -f /nexus-data/admin.password; do sleep 10; done'

# 获取初始管理员密码
ADMIN_PASSWORD=$(docker exec nexus3 cat /nexus-data/admin.password)
echo "初始管理员密码: $ADMIN_PASSWORD"

# 保存密码到文件
echo "$ADMIN_PASSWORD" > admin-password.txt
chmod 600 admin-password.txt

Web 界面初始化
#

  1. 访问管理界面http://your-server-ip:8081
  2. 登录系统
    • 用户名:admin
    • 密码:使用上面获取的初始密码
  3. 完成设置向导
    • 修改管理员密码
    • 配置匿名访问权限
    • 选择改进计划参与方式

Nexus3 初始化界面

图:Nexus3 初始化配置界面

自动化初始配置脚本
#

cat > init-nexus.sh << 'EOF'
#!/bin/bash

NEXUS_URL="http://localhost:8081"
ADMIN_USER="admin"
ADMIN_PASS=$(cat admin-password.txt)
NEW_ADMIN_PASS="YourSecurePassword123!"

echo "=== Nexus3 自动化初始配置 ==="

# 等待 Nexus3 API 可用
echo "等待 Nexus3 API 可用..."
timeout 300 bash -c 'until curl -f $NEXUS_URL/service/rest/v1/status; do sleep 10; done'

# 修改管理员密码
echo "修改管理员密码..."
curl -X PUT "$NEXUS_URL/service/rest/v1/security/users/admin/change-password" \
  -H "Content-Type: text/plain" \
  -u "$ADMIN_USER:$ADMIN_PASS" \
  -d "$NEW_ADMIN_PASS"

# 禁用匿名访问
echo "配置匿名访问..."
curl -X PUT "$NEXUS_URL/service/rest/v1/security/anonymous" \
  -H "Content-Type: application/json" \
  -u "$ADMIN_USER:$NEW_ADMIN_PASS" \
  -d '{"enabled": false, "userId": "anonymous", "realmName": "NexusAuthorizingRealm"}'

# 创建 Blob Store
echo "创建 Blob Store..."
curl -X POST "$NEXUS_URL/service/rest/v1/blobstores/file" \
  -H "Content-Type: application/json" \
  -u "$ADMIN_USER:$NEW_ADMIN_PASS" \
  -d '{
    "name": "docker-blob",
    "softQuota": {
      "type": "spaceUsedQuota",
      "limit": 100000000000
    },
    "path": "docker-blob"
  }'

echo "✓ 初始配置完成"
echo "新管理员密码: $NEW_ADMIN_PASS"
EOF

chmod +x init-nexus.sh
./init-nexus.sh

仓库配置管理
#

Maven 仓库配置
#

默认 Maven 仓库
#

Nexus3 默认提供以下 Maven 仓库:

  • maven-central: Maven 中央仓库代理
  • maven-releases: 发布版本仓库(hosted)
  • maven-snapshots: 快照版本仓库(hosted)
  • maven-public: 仓库组(group)

添加国内镜像仓库
#

# 创建阿里云 Maven 代理仓库
cat > create-maven-aliyun.sh << 'EOF'
#!/bin/bash

NEXUS_URL="http://localhost:8081"
ADMIN_USER="admin"
ADMIN_PASS="YourSecurePassword123!"

curl -X POST "$NEXUS_URL/service/rest/v1/repositories/maven/proxy" \
  -H "Content-Type: application/json" \
  -u "$ADMIN_USER:$ADMIN_PASS" \
  -d '{
    "name": "maven-aliyun",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true
    },
    "proxy": {
      "remoteUrl": "https://maven.aliyun.com/repository/public",
      "contentMaxAge": 1440,
      "metadataMaxAge": 1440
    },
    "negativeCache": {
      "enabled": true,
      "timeToLive": 1440
    },
    "httpClient": {
      "blocked": false,
      "autoBlock": true
    },
    "maven": {
      "versionPolicy": "MIXED",
      "layoutPolicy": "STRICT"
    }
  }'

echo "✓ 阿里云 Maven 仓库创建完成"
EOF

chmod +x create-maven-aliyun.sh
./create-maven-aliyun.sh

配置 Maven 客户端
#

<!-- ~/.m2/settings.xml -->
<settings>
  <mirrors>
    <mirror>
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <name>Nexus Repository</name>
      <url>http://your-nexus-server:8081/repository/maven-public/</url>
    </mirror>
  </mirrors>

  <servers>
    <server>
      <id>nexus-releases</id>
      <username>admin</username>
      <password>YourSecurePassword123!</password>
    </server>
    <server>
      <id>nexus-snapshots</id>
      <username>admin</username>
      <password>YourSecurePassword123!</password>
    </server>
  </servers>
</settings>

Docker 仓库配置
#

创建 Docker 仓库
#

cat > create-docker-repos.sh << 'EOF'
#!/bin/bash

NEXUS_URL="http://localhost:8081"
ADMIN_USER="admin"
ADMIN_PASS="YourSecurePassword123!"

# 创建 Docker Hosted 仓库
echo "创建 Docker Hosted 仓库..."
curl -X POST "$NEXUS_URL/service/rest/v1/repositories/docker/hosted" \
  -H "Content-Type: application/json" \
  -u "$ADMIN_USER:$ADMIN_PASS" \
  -d '{
    "name": "docker-hosted",
    "online": true,
    "storage": {
      "blobStoreName": "docker-blob",
      "strictContentTypeValidation": true,
      "writePolicy": "ALLOW"
    },
    "docker": {
      "v1Enabled": false,
      "forceBasicAuth": true,
      "httpPort": 8083
    }
  }'

# 创建 Docker Proxy 仓库
echo "创建 Docker Proxy 仓库..."
curl -X POST "$NEXUS_URL/service/rest/v1/repositories/docker/proxy" \
  -H "Content-Type: application/json" \
  -u "$ADMIN_USER:$ADMIN_PASS" \
  -d '{
    "name": "docker-proxy",
    "online": true,
    "storage": {
      "blobStoreName": "docker-blob",
      "strictContentTypeValidation": true
    },
    "proxy": {
      "remoteUrl": "https://registry-1.docker.io",
      "contentMaxAge": 1440,
      "metadataMaxAge": 1440
    },
    "negativeCache": {
      "enabled": true,
      "timeToLive": 1440
    },
    "httpClient": {
      "blocked": false,
      "autoBlock": true
    },
    "docker": {
      "v1Enabled": false,
      "forceBasicAuth": true,
      "httpPort": 8082
    },
    "dockerProxy": {
      "indexType": "HUB"
    }
  }'

# 创建 Docker Group 仓库
echo "创建 Docker Group 仓库..."
curl -X POST "$NEXUS_URL/service/rest/v1/repositories/docker/group" \
  -H "Content-Type: application/json" \
  -u "$ADMIN_USER:$ADMIN_PASS" \
  -d '{
    "name": "docker-group",
    "online": true,
    "storage": {
      "blobStoreName": "docker-blob",
      "strictContentTypeValidation": true
    },
    "group": {
      "memberNames": ["docker-hosted", "docker-proxy"]
    },
    "docker": {
      "v1Enabled": false,
      "forceBasicAuth": true,
      "httpPort": 8084
    }
  }'

echo "✓ Docker 仓库创建完成"
EOF

chmod +x create-docker-repos.sh
./create-docker-repos.sh

配置 Docker 客户端
#

# 配置 Docker daemon
cat > /etc/docker/daemon.json << 'EOF'
{
  "insecure-registries": [
    "your-nexus-server:8082",
    "your-nexus-server:8083",
    "your-nexus-server:8084"
  ],
  "registry-mirrors": [
    "http://your-nexus-server:8082"
  ]
}
EOF

# 重启 Docker 服务
systemctl restart docker

# 登录到 Nexus Docker 仓库
docker login your-nexus-server:8083

NPM 仓库配置
#

创建 NPM 仓库
#

cat > create-npm-repos.sh << 'EOF'
#!/bin/bash

NEXUS_URL="http://localhost:8081"
ADMIN_USER="admin"
ADMIN_PASS="YourSecurePassword123!"

# 创建 NPM Proxy 仓库
echo "创建 NPM Proxy 仓库..."
curl -X POST "$NEXUS_URL/service/rest/v1/repositories/npm/proxy" \
  -H "Content-Type: application/json" \
  -u "$ADMIN_USER:$ADMIN_PASS" \
  -d '{
    "name": "npm-proxy",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true
    },
    "proxy": {
      "remoteUrl": "https://registry.npmjs.org",
      "contentMaxAge": 1440,
      "metadataMaxAge": 1440
    },
    "negativeCache": {
      "enabled": true,
      "timeToLive": 1440
    },
    "httpClient": {
      "blocked": false,
      "autoBlock": true
    }
  }'

# 创建 NPM Hosted 仓库
echo "创建 NPM Hosted 仓库..."
curl -X POST "$NEXUS_URL/service/rest/v1/repositories/npm/hosted" \
  -H "Content-Type: application/json" \
  -u "$ADMIN_USER:$ADMIN_PASS" \
  -d '{
    "name": "npm-hosted",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true,
      "writePolicy": "ALLOW"
    }
  }'

# 创建 NPM Group 仓库
echo "创建 NPM Group 仓库..."
curl -X POST "$NEXUS_URL/service/rest/v1/repositories/npm/group" \
  -H "Content-Type: application/json" \
  -u "$ADMIN_USER:$ADMIN_PASS" \
  -d '{
    "name": "npm-group",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true
    },
    "group": {
      "memberNames": ["npm-hosted", "npm-proxy"]
    }
  }'

echo "✓ NPM 仓库创建完成"
EOF

chmod +x create-npm-repos.sh
./create-npm-repos.sh

配置 NPM 客户端
#

# 配置 NPM 使用 Nexus 仓库
npm config set registry http://your-nexus-server:8081/repository/npm-group/

# 配置认证
npm login --registry=http://your-nexus-server:8081/repository/npm-hosted/

监控与告警
#

健康检查监控
#

创建监控脚本
#

cat > nexus-monitor.sh << 'EOF'
#!/bin/bash

NEXUS_URL="http://localhost:8081"
CONTAINER_NAME="nexus3"
LOG_FILE="/var/log/nexus-monitor.log"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# 检查容器状态
check_container() {
    if docker ps --filter "name=$CONTAINER_NAME" --format "{{.Names}}" | grep -q $CONTAINER_NAME; then
        log "✓ Nexus3 容器运行正常"
        return 0
    else
        log "✗ Nexus3 容器未运行"
        return 1
    fi
}

# 检查 Web 服务
check_web_service() {
    local response_code=$(curl -s -o /dev/null -w "%{http_code}" $NEXUS_URL)
    if [ "$response_code" = "200" ]; then
        log "✓ Nexus3 Web 服务响应正常"
        return 0
    else
        log "✗ Nexus3 Web 服务响应异常 (HTTP $response_code)"
        return 1
    fi
}

# 检查 API 服务
check_api_service() {
    local api_response=$(curl -s "$NEXUS_URL/service/rest/v1/status")
    if echo "$api_response" | grep -q "available"; then
        log "✓ Nexus3 API 服务正常"
        return 0
    else
        log "✗ Nexus3 API 服务异常"
        return 1
    fi
}

# 检查磁盘空间
check_disk_space() {
    local usage=$(df /data/nexus3 | awk 'NR==2 {print $5}' | sed 's/%//')
    if [ $usage -lt 80 ]; then
        log "✓ 磁盘空间充足 (${usage}%)"
        return 0
    elif [ $usage -lt 90 ]; then
        log "⚠ 磁盘空间不足 (${usage}%)"
        return 1
    else
        log "✗ 磁盘空间严重不足 (${usage}%)"
        return 2
    fi
}

# 检查内存使用
check_memory_usage() {
    local memory_usage=$(docker stats $CONTAINER_NAME --no-stream --format "{{.MemPerc}}" | sed 's/%//')
    if (( $(echo "$memory_usage < 80" | bc -l) )); then
        log "✓ 内存使用正常 (${memory_usage}%)"
        return 0
    else
        log "⚠ 内存使用较高 (${memory_usage}%)"
        return 1
    fi
}

# 发送告警
send_alert() {
    local message="$1"
    local severity="$2"

    # 邮件告警
    if command -v mail >/dev/null 2>&1; then
        echo "$message" | mail -s "Nexus3 监控告警 [$severity]" admin@your-domain.com
    fi

    # 钉钉告警
    if [ -n "$DINGTALK_WEBHOOK" ]; then
        curl -X POST "$DINGTALK_WEBHOOK" \
            -H 'Content-Type: application/json' \
            -d "{\"msgtype\": \"text\", \"text\": {\"content\": \"Nexus3 告警: $message\"}}"
    fi
}

# 主监控函数
main() {
    log "=== Nexus3 监控检查开始 ==="

    local issues=0
    local critical_issues=0

    check_container || ((issues++))
    check_web_service || ((issues++))
    check_api_service || ((issues++))

    check_disk_space
    local disk_status=$?
    if [ $disk_status -eq 2 ]; then
        ((critical_issues++))
        send_alert "Nexus3 磁盘空间严重不足" "CRITICAL"
    elif [ $disk_status -eq 1 ]; then
        ((issues++))
    fi

    check_memory_usage || ((issues++))

    if [ $critical_issues -gt 0 ]; then
        log "✗ 发现 $critical_issues 个严重问题"
        send_alert "Nexus3 监控发现 $critical_issues 个严重问题" "CRITICAL"
    elif [ $issues -gt 0 ]; then
        log "⚠ 发现 $issues 个问题"
        send_alert "Nexus3 监控发现 $issues 个问题" "WARNING"
    else
        log "✓ 所有检查通过"
    fi

    log "=== Nexus3 监控检查完成 ==="
}

main "$@"
EOF

chmod +x nexus-monitor.sh

# 设置定时监控
echo "*/5 * * * * /data/nexus3/nexus-monitor.sh" | crontab -

Prometheus 监控集成
#

启用 Nexus3 指标
#

# 在 docker-compose.yml 中添加 JMX 监控
cat >> docker-compose.yml << 'EOF'
    environment:
      - INSTALL4J_ADD_VM_PARAMS=-Xms4g -Xmx4g -XX:MaxDirectMemorySize=6g -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
    ports:
      - "9999:9999"  # JMX 端口
EOF

Prometheus 配置
#

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'nexus3'
    static_configs:
      - targets: ['nexus3:9999']
    metrics_path: '/metrics'
    scrape_interval: 30s

备份与恢复
#

数据备份策略
#

完整备份脚本
#

cat > nexus-backup.sh << 'EOF'
#!/bin/bash

BACKUP_DIR="/data/nexus3/backup"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
NEXUS_DATA_DIR="/data/nexus3/data"

echo "=== Nexus3 备份脚本 ==="
echo "开始时间: $(date)"

# 创建备份目录
mkdir -p $BACKUP_DIR

# 停止 Nexus3 服务(可选,用于一致性备份)
read -p "是否停止 Nexus3 服务进行一致性备份?(y/N): " STOP_SERVICE
if [[ $STOP_SERVICE =~ ^[Yy]$ ]]; then
    echo "停止 Nexus3 服务..."
    docker-compose stop nexus3
    RESTART_NEEDED=true
fi

# 创建数据备份
echo "创建数据备份..."
tar -czf "$BACKUP_DIR/nexus-data-$DATE.tar.gz" \
    --exclude="$NEXUS_DATA_DIR/log/*" \
    --exclude="$NEXUS_DATA_DIR/tmp/*" \
    -C "$(dirname $NEXUS_DATA_DIR)" \
    "$(basename $NEXUS_DATA_DIR)"

# 备份 Docker Compose 配置
echo "备份配置文件..."
cp docker-compose.yml "$BACKUP_DIR/docker-compose-$DATE.yml"

# 重启服务(如果之前停止了)
if [[ $RESTART_NEEDED == true ]]; then
    echo "重启 Nexus3 服务..."
    docker-compose up -d nexus3
fi

# 验证备份
if [ -f "$BACKUP_DIR/nexus-data-$DATE.tar.gz" ]; then
    BACKUP_SIZE=$(du -h "$BACKUP_DIR/nexus-data-$DATE.tar.gz" | cut -f1)
    echo "✓ 备份完成: nexus-data-$DATE.tar.gz ($BACKUP_SIZE)"
else
    echo "✗ 备份失败"
    exit 1
fi

# 清理过期备份
echo "清理过期备份..."
find $BACKUP_DIR -name "nexus-data-*.tar.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "docker-compose-*.yml" -mtime +$RETENTION_DAYS -delete

echo "=== 备份完成 ==="
EOF

chmod +x nexus-backup.sh

# 设置定时备份
echo "0 2 * * * /data/nexus3/nexus-backup.sh" | crontab -

数据恢复
#

恢复脚本
#

cat > nexus-restore.sh << 'EOF'
#!/bin/bash

BACKUP_DIR="/data/nexus3/backup"
NEXUS_DATA_DIR="/data/nexus3/data"

echo "=== Nexus3 数据恢复脚本 ==="

# 列出可用备份
echo "可用的备份文件:"
ls -la $BACKUP_DIR/nexus-data-*.tar.gz | nl

# 选择备份文件
read -p "请输入要恢复的备份文件编号: " BACKUP_NUM
BACKUP_FILE=$(ls $BACKUP_DIR/nexus-data-*.tar.gz | sed -n "${BACKUP_NUM}p")

if [ ! -f "$BACKUP_FILE" ]; then
    echo "备份文件不存在: $BACKUP_FILE"
    exit 1
fi

echo "选择的备份文件: $BACKUP_FILE"
read -p "确认恢复?这将覆盖现有数据 (yes/no): " CONFIRM

if [ "$CONFIRM" != "yes" ]; then
    echo "恢复已取消"
    exit 0
fi

# 停止 Nexus3 服务
echo "停止 Nexus3 服务..."
docker-compose stop nexus3

# 备份当前数据
echo "备份当前数据..."
mv $NEXUS_DATA_DIR ${NEXUS_DATA_DIR}.backup.$(date +%Y%m%d_%H%M%S)

# 恢复数据
echo "恢复数据..."
mkdir -p $(dirname $NEXUS_DATA_DIR)
tar -xzf "$BACKUP_FILE" -C $(dirname $NEXUS_DATA_DIR)

# 修复权限
echo "修复权限..."
chown -R 200:200 $NEXUS_DATA_DIR

# 启动 Nexus3 服务
echo "启动 Nexus3 服务..."
docker-compose up -d nexus3

echo "✓ 数据恢复完成"
echo "请等待服务启动并验证功能"
EOF

chmod +x nexus-restore.sh

故障排除
#

常见问题诊断
#

启动问题
#

cat > diagnose-nexus.sh << 'EOF'
#!/bin/bash

echo "=== Nexus3 故障诊断 ==="

# 检查容器状态
echo "1. 检查容器状态"
docker ps -a --filter "name=nexus3"

# 检查容器日志
echo -e "\n2. 检查容器日志"
docker logs --tail 50 nexus3

# 检查磁盘空间
echo -e "\n3. 检查磁盘空间"
df -h /data/nexus3

# 检查内存使用
echo -e "\n4. 检查内存使用"
free -h

# 检查网络连接
echo -e "\n5. 检查网络连接"
netstat -tlnp | grep -E "(8081|8082|8083)"

# 检查 Java 进程
echo -e "\n6. 检查 Java 进程"
docker exec nexus3 ps aux | grep java

echo -e "\n=== 诊断完成 ==="
EOF

chmod +x diagnose-nexus.sh

总结
#

部署优势
#

通过本指南,您可以成功部署一个企业级的 Nexus3 制品仓库平台,具有以下优势:

技术优势
#

  • 统一制品管理:支持 20+ 种包格式的统一管理
  • 高性能架构:基于现代化架构,支持大规模并发访问
  • 企业级安全:细粒度权限控制、LDAP 集成
  • 智能代理:缓存外部仓库,提供离线访问能力
  • 可扩展性:支持集群部署和水平扩展

运维优势
#

  • 容器化部署:标准化部署流程,环境一致性好
  • 自动化备份:完整的备份恢复策略
  • 监控告警:全面的监控和告警体系
  • 故障排除:完善的诊断和恢复机制

最佳实践
#

生产环境建议
#

  1. 资源规划:根据制品数量和用户规模合理规划资源
  2. 安全配置:启用 HTTPS、配置防火墙、定期安全审计
  3. 备份策略:建立完善的备份和灾难恢复计划
  4. 监控告警:部署全面的监控和告警体系
  5. 性能调优:根据使用情况持续优化 JVM 参数

扩展建议
#

  • 高可用部署:配置多节点集群和负载均衡
  • 对象存储集成:使用 S3 兼容存储降低成本
  • CI/CD 集成:与 Jenkins、GitLab CI 等工具深度集成
  • 安全扫描:集成漏洞扫描和合规性检查

持续改进
#

Nexus3 作为制品管理平台的核心,需要持续优化和改进:

  • 定期更新:保持 Nexus3 版本的及时更新
  • 性能监控:持续监控系统性能和用户体验
  • 安全审计:定期进行安全检查和漏洞扫描
  • 用户培训:提供制品管理最佳实践培训

通过本指南的配置和最佳实践,您可以构建一个稳定、高效、安全的企业级制品仓库平台,为团队的软件开发和交付提供强有力的支撑。

配置 Nginx 反向代理
#

为了提供更好的访问体验和安全性,我们使用 Nginx 作为 Nexus3 的反向代理。这样可以实现:

  • 统一的访问入口
  • SSL/TLS 终端
  • 负载均衡(多实例部署时)
  • 访问日志记录

第一步:安装和配置 Nginx
#

安装 Nginx
#

# 安装 Nginx
yum install -y nginx

# 创建专用用户
useradd -M -s /sbin/nologin www

# 备份原始配置
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup

优化 Nginx 主配置
#

创建针对 Nexus3 优化的 Nginx 配置:

cat > /etc/nginx/nginx.conf << 'EOF'
# Nginx 主配置文件 - 针对 Nexus3 优化
user www www;
worker_processes auto;

# 错误日志配置
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

# 工作进程文件描述符限制
worker_rlimit_nofile 65535;

events {
    # 使用 epoll 事件模型(Linux 推荐)
    use epoll;
    worker_connections 8192;
    multi_accept on;
    accept_mutex off;
}

http {
    # 基础配置
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # 服务器标识
    server_tokens off;

    # 哈希表大小
    server_names_hash_bucket_size 128;
    server_names_hash_max_size 512;

    # 客户端请求配置
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 0;              # 允许大文件上传
    client_body_buffer_size 128k;
    client_body_timeout 60s;
    client_header_timeout 60s;

    # 发送文件优化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # 连接超时设置
    keepalive_timeout 65;
    keepalive_requests 1000;

    # 代理配置
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;
    proxy_buffer_size 64k;
    proxy_buffers 4 64k;
    proxy_busy_buffers_size 128k;
    proxy_temp_file_write_size 128k;
    proxy_intercept_errors off;

    # Gzip 压缩配置
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml
        image/svg+xml;
    gzip_disable "MSIE [1-6]\.";

    # 日志格式定义
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    log_format json_combined escape=json
        '{'
            '"time_local":"$time_local",'
            '"remote_addr":"$remote_addr",'
            '"remote_user":"$remote_user",'
            '"request":"$request",'
            '"status": "$status",'
            '"body_bytes_sent":"$body_bytes_sent",'
            '"request_time":"$request_time",'
            '"http_referrer":"$http_referer",'
            '"http_user_agent":"$http_user_agent",'
            '"http_x_forwarded_for":"$http_x_forwarded_for",'
            '"upstream_addr":"$upstream_addr",'
            '"upstream_status":"$upstream_status",'
            '"upstream_response_time":"$upstream_response_time"'
        '}';

    # 默认访问日志
    access_log /var/log/nginx/access.log main;

    # 包含虚拟主机配置
    include /etc/nginx/conf.d/*.conf;
}
EOF

# 测试配置文件语法
nginx -t

第二步:配置 Nexus3 虚拟主机
#

创建 Nexus3 专用配置
#

cat > /etc/nginx/conf.d/nexus3.conf << 'EOF'
# Nexus3 反向代理配置

# 上游服务器定义
upstream nexus_web {
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

upstream nexus_docker_read {
    server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

upstream nexus_docker_write {
    server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

# Docker 仓库配置
server {
    listen 80;
    server_name docker.example.com;  # 请修改为您的域名

    # 访问日志
    access_log /var/log/nginx/docker.example.com.log json_combined;
    error_log /var/log/nginx/docker.example.com.error.log;

    # 客户端配置
    client_max_body_size 0;
    chunked_transfer_encoding on;

    # 根据请求方法选择上游服务器
    set $upstream "nexus_docker_write";
    if ($request_method ~ ^(GET|HEAD)$ ) {
        set $upstream "nexus_docker_read";
    }

    # Docker API 搜索请求特殊处理
    if ($request_uri ~ '/v2/_catalog' ) {
        set $upstream "nexus_docker_write";
    }
    if ($request_uri ~ '/v2/search' ) {
        set $upstream "nexus_docker_write";
    }

    location / {
        proxy_pass http://$upstream;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 禁用缓冲以支持大文件上传
        proxy_buffering off;
        proxy_request_buffering off;

        # 超时设置
        proxy_connect_timeout 300s;
        proxy_send_timeout 300s;
        proxy_read_timeout 300s;

        # 支持 WebSocket(如果需要)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # 健康检查端点
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}

# Nexus3 Web 管理界面配置
server {
    listen 80;
    server_name nexus.example.com;  # 请修改为您的域名

    # 访问日志
    access_log /var/log/nginx/nexus.example.com.log json_combined;
    error_log /var/log/nginx/nexus.example.com.error.log;

    # 客户端配置
    client_max_body_size 0;
    proxy_max_temp_file_size 0;

    location / {
        proxy_pass http://nexus_web;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 超时设置
        proxy_connect_timeout 300s;
        proxy_send_timeout 300s;
        proxy_read_timeout 300s;

        # 支持 WebSocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # 静态文件下载目录(可选)
    location /download {
        alias /application/download;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
    }
}
EOF

第三步:启动和验证 Nginx
#

# 启动 Nginx 服务
systemctl start nginx
systemctl enable nginx

# 检查服务状态
systemctl status nginx

# 验证配置
nginx -t

# 重新加载配置(如果需要修改)
nginx -s reload

# 检查端口监听
netstat -tlnp | grep nginx

SSL/TLS 配置(推荐)
#

使用 Let’s Encrypt 免费证书
#

# 安装 Certbot
yum install -y epel-release
yum install -y certbot python2-certbot-nginx

# 获取证书
certbot --nginx -d nexus.example.com -d docker.example.com

# 设置自动续期
echo "0 12 * * * /usr/bin/certbot renew --quiet" | crontab -

手动 SSL 配置示例
#

server {
    listen 443 ssl http2;
    server_name nexus.example.com;

    # SSL 证书配置
    ssl_certificate /etc/ssl/certs/nexus.example.com.crt;
    ssl_certificate_key /etc/ssl/private/nexus.example.com.key;

    # SSL 安全配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # 其他配置同 HTTP 版本
    # ...
}

配置 Docker 私有仓库
#

Docker 私有仓库是 Nexus3 最常用的功能之一。我们需要创建三种类型的仓库来实现完整的 Docker 镜像管理。

第一步:创建 Blob 存储
#

Blob 存储是 Nexus3 中用于存储二进制文件的底层存储机制。

创建 Docker 专用 Blob 存储
#

  1. 登录 Nexus3 管理界面

    • 访问:http://your-server:8081
    • 使用管理员账户登录
  2. 导航到 Blob Stores

    • 点击左侧菜单:RepositoryBlob Stores
  3. 创建新的 Blob Store

    • 点击 Create Blob Store
    • 选择 File 类型
    • 配置参数:
参数说明
Namedocker-blobBlob 存储名称
Pathdocker存储路径(相对于 nexus-data)

创建 Docker Blob 存储

图:创建 Docker 专用的 Blob 存储配置界面

Blob 存储配置详情

图:Blob 存储的详细配置参数

第二步:创建 Docker Hosted 仓库
#

Hosted 仓库用于存储企业内部构建的 Docker 镜像。

配置步骤
#

  1. 导航到仓库管理

    • 点击:RepositoryRepositories
  2. 创建新仓库

    • 点击 Create repository
    • 选择 docker (hosted)
  3. 配置 Hosted 仓库参数

参数说明
Namedocker-hosted仓库名称
HTTP Port8083推送端口
Enable Docker V1 API☑️支持 Docker V1 API
Blob storedocker-blob使用前面创建的 Blob 存储
Deployment policyAllow redeploy允许重新部署

创建 Docker Hosted 仓库

图:选择 Docker Hosted 仓库类型

Docker Hosted 配置

图:Docker Hosted 仓库的基本配置

Docker Hosted 高级配置

图:Docker Hosted 仓库的高级配置选项

第三步:创建 Docker Proxy 仓库
#

Proxy 仓库用于代理外部的 Docker 镜像仓库,提供缓存和加速功能。

配置步骤
#

  1. 创建 Proxy 仓库

    • 选择 docker (proxy)
  2. 配置 Proxy 仓库参数

参数说明
Namedocker-proxy仓库名称
HTTP Port8082拉取端口
Remote storagehttps://registry-1.docker.ioDocker Hub 官方地址
Docker IndexUse Docker Hub使用 Docker Hub 索引
Blob storedocker-blob使用相同的 Blob 存储

推荐的代理地址

  • Docker Hub: https://registry-1.docker.io
  • 阿里云镜像: https://7bezldxe.mirror.aliyuncs.com
  • 腾讯云镜像: https://mirror.ccs.tencentyun.com
  • 网易云镜像: https://hub-mirror.c.163.com

创建 Docker Proxy 仓库

图:选择 Docker Proxy 仓库类型

Docker Proxy 配置

图:Docker Proxy 仓库的远程存储配置

Docker Proxy 高级配置

图:Docker Proxy 仓库的高级配置选项

第四步:创建 Docker Group 仓库
#

Group 仓库将多个仓库组合成一个统一的访问入口。

配置步骤
#

  1. 创建 Group 仓库

    • 选择 docker (group)
  2. 配置 Group 仓库参数

参数说明
Namedocker-group仓库名称
HTTP Port8082统一访问端口
Blob storedocker-blob使用相同的 Blob 存储
Member repositoriesdocker-hosted, docker-proxy包含的仓库

重要提示: 仓库的顺序决定了查找优先级,建议将 docker-hosted 放在前面。

创建 Docker Group 仓库

图:选择 Docker Group 仓库类型

Docker Group 配置

图:Docker Group 仓库的成员配置

第五步:启用 Docker Bearer Token
#

Docker 仓库需要启用 Bearer Token 认证才能正常工作。

配置步骤
#

  1. 导航到安全设置

    • 点击:SecurityRealms
  2. 启用 Docker Bearer Token Realm

    • Docker Bearer Token Realm 从左侧移动到右侧
    • 点击 Save 保存配置

启用 Docker Bearer Token

图:安全域配置界面

Docker Bearer Token 配置

图:启用 Docker Bearer Token Realm

第六步:验证配置
#

检查端口监听
#

# 检查 Nexus3 端口是否正常监听
netstat -tlnp | grep -E "8081|8082|8083"

# 预期输出:
# tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 1393/java
# tcp 0 0 0.0.0.0:8082 0.0.0.0:* LISTEN 1393/java
# tcp 0 0 0.0.0.0:8083 0.0.0.0:* LISTEN 1393/java

测试仓库连通性
#

# 测试 Web 界面
curl -I http://localhost:8081

# 测试 Docker 仓库
curl -I http://localhost:8082/v2/

# 预期返回 401 Unauthorized(需要认证)

第七步:查看配置结果
#

完成所有配置后,您应该能在 Nexus3 管理界面中看到以下仓库:

所有 Docker 仓库展示

图:完成配置后的 Docker 仓库列表

Docker 客户端配置和测试
#

第一步:配置 Docker 客户端
#

配置 Docker Daemon
#

在需要使用私有仓库的客户端机器上配置 Docker:

# 创建或编辑 Docker 配置文件
sudo mkdir -p /etc/docker

cat > /etc/docker/daemon.json << 'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  },
  "max-concurrent-downloads": 10,
  "max-concurrent-uploads": 10,
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ],
  "registry-mirrors": [
    "http://docker.example.com"
  ],
  "insecure-registries": [
    "docker.example.com",
    "nexus.example.com:8082",
    "nexus.example.com:8083"
  ]
}
EOF

配置说明:

  • registry-mirrors: 配置镜像加速器
  • insecure-registries: 允许使用 HTTP 协议的私有仓库
  • max-concurrent-downloads/uploads: 并发下载/上传数量

配置 DNS 解析
#

如果使用域名访问,需要配置 DNS 解析:

# 方法一:修改 /etc/hosts 文件
echo "192.168.1.100 docker.example.com nexus.example.com" >> /etc/hosts

# 方法二:配置 DNS 服务器(推荐生产环境)
# 在您的 DNS 服务器中添加 A 记录

第二步:重启 Docker 服务
#

# 重启 Docker 服务
sudo systemctl restart docker

# 检查服务状态
sudo systemctl status docker

# 验证配置
docker info | grep -A 10 "Registry Mirrors"

第三步:登录私有仓库
#

# 登录到私有仓库
docker login docker.example.com -u admin

# 输入密码(您在初始化时设置的密码)
# 成功后会显示:Login Succeeded

第四步:测试镜像推送和拉取
#

推送镜像测试
#

# 1. 拉取一个公共镜像
docker pull alpine:latest

# 2. 为镜像打标签
docker tag alpine:latest docker.example.com/alpine:latest

# 3. 推送到私有仓库
docker push docker.example.com/alpine:latest

# 4. 验证推送结果
echo "推送完成,可以在 Nexus3 Web 界面查看"

拉取镜像测试
#

# 1. 删除本地镜像
docker rmi docker.example.com/alpine:latest
docker rmi alpine:latest

# 2. 从私有仓库拉取
docker pull docker.example.com/alpine:latest

# 3. 验证拉取结果
docker images | grep alpine

镜像推送成功示例

图:成功推送镜像到私有仓库的示例

第五步:批量镜像迁移
#

创建镜像迁移脚本
#

cat > /usr/local/bin/docker-migrate.sh << 'EOF'
#!/bin/bash
# Docker 镜像批量迁移脚本

PRIVATE_REGISTRY="docker.example.com"
IMAGES_FILE="/tmp/images.txt"

# 获取本地所有镜像
docker images --format "table {{.Repository}}:{{.Tag}}" | grep -v "REPOSITORY:TAG" > $IMAGES_FILE

echo "开始迁移镜像到私有仓库..."

while IFS= read -r image; do
    if [[ "$image" != *"$PRIVATE_REGISTRY"* ]]; then
        echo "处理镜像: $image"

        # 为镜像打标签
        new_tag="$PRIVATE_REGISTRY/$image"
        docker tag "$image" "$new_tag"

        # 推送到私有仓库
        if docker push "$new_tag"; then
            echo "✅ 成功推送: $new_tag"
        else
            echo "❌ 推送失败: $new_tag"
        fi

        # 删除临时标签
        docker rmi "$new_tag" 2>/dev/null
    fi
done < "$IMAGES_FILE"

echo "镜像迁移完成!"
rm -f "$IMAGES_FILE"
EOF

chmod +x /usr/local/bin/docker-migrate.sh

使用迁移脚本
#

# 执行镜像迁移
/usr/local/bin/docker-migrate.sh

故障排除
#

常见问题及解决方案
#

问题可能原因解决方案
x509: certificate signed by unknown authoritySSL 证书问题添加到 insecure-registries 或配置正确的证书
dial tcp: lookup docker.example.com: no such hostDNS 解析失败检查 DNS 配置或 /etc/hosts 文件
unauthorized: authentication required认证失败检查用户名密码,确保已启用 Docker Bearer Token
denied: requested access to the resource is denied权限不足检查用户权限和仓库访问策略

调试命令
#

# 查看 Docker 配置
docker info

# 测试网络连通性
telnet docker.example.com 80

# 查看 Docker 日志
journalctl -u docker.service -f

# 测试仓库 API
curl -v http://docker.example.com/v2/

Nexus3 版本升级指南
#

Nexus3 的定期升级是维护系统安全性和稳定性的重要措施。Sonatype 官方建议定期更新 Nexus3 版本以获得最新的安全补丁和功能改进。

升级前准备
#

第一步:备份数据
#

重要提示: 升级前必须备份数据,以防升级失败时能够快速恢复。

# 停止 Nexus3 服务
docker stop nexus3

# 创建数据备份
BACKUP_DIR="/backup/nexus3-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"

# 备份数据目录
cp -r /application/nexus3/data "$BACKUP_DIR/"

# 备份 Docker 配置
docker inspect nexus3 > "$BACKUP_DIR/container-config.json"

# 创建压缩备份(可选)
tar -czf "$BACKUP_DIR.tar.gz" -C /application/nexus3 data

echo "备份完成: $BACKUP_DIR"

第二步:检查版本兼容性
#

# 查看当前版本
docker exec nexus3 cat /opt/sonatype/nexus/VERSION 2>/dev/null || echo "容器未运行"

# 查看可用版本
curl -s https://registry.hub.docker.com/v2/repositories/sonatype/nexus3/tags/ | \
  jq -r '.results[].name' | head -10

版本选择建议:

  • 优先选择 LTS(长期支持)版本
  • 避免跨越多个大版本升级
  • 查看 官方发布说明 了解重大变更

第三步:制定升级计划
#

升级类型风险等级建议策略
补丁版本 (3.27.0 → 3.27.1)可直接升级
次要版本 (3.27.x → 3.28.x)建议测试环境验证
主要版本 (3.x → 4.x)必须详细测试和规划

升级执行
#

标准升级流程
#

以下示例将 Nexus3 从 3.28.1 升级到 3.29.2:

#!/bin/bash
# Nexus3 升级脚本

set -e  # 遇到错误立即退出

# 配置变量
OLD_VERSION="3.28.1"
NEW_VERSION="3.29.2"
CONTAINER_NAME="nexus3"
BACKUP_DIR="/backup/nexus3-upgrade-$(date +%Y%m%d-%H%M%S)"

echo "开始 Nexus3 升级流程..."
echo "当前版本: $OLD_VERSION"
echo "目标版本: $NEW_VERSION"

# 1. 创建备份
echo "步骤 1: 创建数据备份..."
mkdir -p "$BACKUP_DIR"
docker stop "$CONTAINER_NAME"
cp -r /application/nexus3/data "$BACKUP_DIR/"
echo "备份完成: $BACKUP_DIR"

# 2. 重命名旧容器
echo "步骤 2: 保留旧容器..."
docker rename "$CONTAINER_NAME" "${CONTAINER_NAME}_${OLD_VERSION}_backup"

# 3. 拉取新镜像
echo "步骤 3: 拉取新版本镜像..."
docker pull "sonatype/nexus3:$NEW_VERSION"

# 4. 启动新容器
echo "步骤 4: 启动新版本容器..."
docker run -d \
  --name "$CONTAINER_NAME" \
  --restart=always \
  --ulimit nofile=65536:65536 \
  -p 8081:8081 \
  -p 8082:8082 \
  -p 8083:8083 \
  -e INSTALL4J_ADD_VM_PARAMS="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=6g -Djava.util.prefs.userRoot=/nexus-data/javaprefs" \
  -v /etc/localtime:/etc/localtime:ro \
  -v /application/nexus3/data:/nexus-data \
  "sonatype/nexus3:$NEW_VERSION"

# 5. 等待服务启动
echo "步骤 5: 等待服务启动..."
sleep 30

# 6. 检查服务状态
echo "步骤 6: 检查服务状态..."
for i in {1..30}; do
    if curl -f -s http://localhost:8081/service/rest/v1/status > /dev/null; then
        echo "✅ Nexus3 服务启动成功"
        break
    fi
    echo "等待服务启动... ($i/30)"
    sleep 10
done

# 7. 验证升级结果
echo "步骤 7: 验证升级结果..."
NEW_RUNNING_VERSION=$(docker exec "$CONTAINER_NAME" cat /opt/sonatype/nexus/VERSION)
echo "当前运行版本: $NEW_RUNNING_VERSION"

if [[ "$NEW_RUNNING_VERSION" == "$NEW_VERSION" ]]; then
    echo "✅ 升级成功!"
    echo "可以通过以下命令删除备份容器:"
    echo "docker rm ${CONTAINER_NAME}_${OLD_VERSION}_backup"
else
    echo "❌ 升级失败,版本不匹配"
    exit 1
fi

手动升级步骤
#

如果不使用脚本,可以按以下步骤手动执行:

# 1. 停止当前容器
docker stop nexus3

# 2. 重命名容器(保留备份)
docker rename nexus3 nexus3_backup

# 3. 拉取新版本镜像
docker pull sonatype/nexus3:3.29.2

# 4. 启动新容器
docker run -d \
  --name nexus3 \
  --restart=always \
  --ulimit nofile=65536:65536 \
  -p 8081:8081 \
  -p 8082:8082 \
  -p 8083:8083 \
  -e INSTALL4J_ADD_VM_PARAMS="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=6g" \
  -v /etc/localtime:/etc/localtime:ro \
  -v /application/nexus3/data:/nexus-data \
  sonatype/nexus3:3.29.2

# 5. 监控启动过程
docker logs -f nexus3

升级后验证
#

功能验证清单
#

# 1. 检查服务状态
curl -I http://localhost:8081

# 2. 验证 Web 界面访问
curl -s http://localhost:8081 | grep -q "Nexus Repository Manager"

# 3. 检查仓库列表
curl -u admin:password http://localhost:8081/service/rest/v1/repositories

# 4. 测试 Docker 仓库
docker pull alpine:latest
docker tag alpine:latest localhost:8082/alpine:test
docker push localhost:8083/alpine:test

# 5. 验证数据完整性
# 检查关键仓库和配置是否正常

性能监控
#

# 监控容器资源使用
docker stats nexus3

# 检查日志中的错误
docker logs nexus3 | grep -i error

# 监控磁盘使用
df -h /application/nexus3/data

升级成功示例

图:Nexus3 升级成功后的日志输出

回滚策略
#

如果升级失败,可以快速回滚到之前的版本:

#!/bin/bash
# Nexus3 回滚脚本

echo "开始回滚 Nexus3..."

# 1. 停止新容器
docker stop nexus3
docker rm nexus3

# 2. 恢复数据(如果需要)
# cp -r /backup/nexus3-backup/data/* /application/nexus3/data/

# 3. 启动备份容器
docker rename nexus3_backup nexus3
docker start nexus3

# 4. 验证回滚结果
sleep 30
if curl -f -s http://localhost:8081/service/rest/v1/status > /dev/null; then
    echo "✅ 回滚成功"
else
    echo "❌ 回滚失败,请检查日志"
fi

升级最佳实践
#

1. 定期升级策略
#

# 创建升级检查脚本
cat > /usr/local/bin/nexus-version-check.sh << 'EOF'
#!/bin/bash
# 检查 Nexus3 新版本

CURRENT_VERSION=$(docker exec nexus3 cat /opt/sonatype/nexus/VERSION 2>/dev/null)
LATEST_VERSION=$(curl -s https://api.github.com/repos/sonatype/nexus-public/releases/latest | jq -r '.tag_name' | sed 's/release-//')

echo "当前版本: $CURRENT_VERSION"
echo "最新版本: $LATEST_VERSION"

if [[ "$CURRENT_VERSION" != "$LATEST_VERSION" ]]; then
    echo "⚠️  发现新版本,建议升级"
else
    echo "✅ 已是最新版本"
fi
EOF

chmod +x /usr/local/bin/nexus-version-check.sh

# 设置定期检查
echo "0 9 * * 1 /usr/local/bin/nexus-version-check.sh | mail -s 'Nexus3 版本检查' admin@example.com" | crontab -

2. 升级注意事项
#

  • 测试环境验证: 先在测试环境进行升级验证
  • 维护窗口: 选择业务低峰期进行升级
  • 通知机制: 提前通知用户升级计划
  • 监控告警: 升级后加强监控,及时发现问题
  • 文档记录: 记录升级过程和遇到的问题

3. 清理工作
#

升级成功并稳定运行一段时间后,可以清理备份:

# 删除备份容器(确认升级成功后)
docker rm nexus3_backup

# 清理旧镜像
docker image prune -f

# 清理过期备份(保留最近3个备份)
find /backup -name "nexus3-*" -type d | sort -r | tail -n +4 | xargs rm -rf

其他类型私有仓库配置
#

Nexus3 支持多种包管理格式,可以为企业提供统一的制品管理平台。以下介绍几种常用的私有仓库配置方法。

官方文档: Nexus3 支持的仓库格式

Yum 私有仓库配置
#

Yum 私有仓库可以为 CentOS/RHEL 系统提供 RPM 包管理服务,特别适合企业内网环境。

第一步:创建 Yum Blob 存储
#

配置 Blob Store
#

  1. 导航到 Blob Stores

    • 点击:RepositoryBlob Stores
  2. 创建新的 Blob Store

    • 点击 Create Blob Store
    • 配置参数:
参数说明
TypeFile文件存储类型
Nameyum-blobBlob 存储名称
Pathyum存储路径

创建 Yum Blob 存储

图:创建 Yum 专用的 Blob 存储

Yum Blob 存储配置

图:Yum Blob 存储的详细配置

第二步:创建 Yum Hosted 仓库
#

配置 Hosted 仓库
#

  1. 创建新仓库

    • 点击:RepositoryRepositoriesCreate repository
    • 选择 yum (hosted)
  2. 配置仓库参数

参数说明
Nameyum-hosted仓库名称
Blob storeyum-blob使用创建的 Blob 存储
Deployment policyAllow redeploy允许重新部署
Repodata Depth3重要: 仓库数据深度

创建 Yum Hosted 仓库

图:选择 Yum Hosted 仓库类型

Yum Hosted 配置

图:Yum Hosted 仓库的详细配置

重要配置说明
#

**Repodata Depth(仓库数据深度)**是 Yum 仓库的关键配置:

Repodata Depth 说明

图:官方文档中关于 Repodata Depth 的说明

深度配置对应关系:

  • 深度 0: /repository/yum-hosted/
  • 深度 1: /repository/yum-hosted/7/
  • 深度 2: /repository/yum-hosted/7/os/
  • 深度 3: /repository/yum-hosted/7/os/x86_64/

推荐配置: 使用深度 3,符合标准的 CentOS 仓库结构。

第三步:准备 RPM 包
#

从 CentOS ISO 提取 RPM 包
#

使用 CentOS 7 完整版 ISO 作为示例:

# 1. 挂载 CentOS ISO 镜像
sudo mkdir -p /mnt/centos-iso
sudo mount -o loop CentOS-7-x86_64-Everything-2003.iso /mnt/centos-iso

# 2. 创建本地工作目录
mkdir -p /tmp/centos7-rpms
cd /tmp/centos7-rpms

# 3. 复制 RPM 包
cp /mnt/centos-iso/Packages/*.rpm ./

# 4. 验证 RPM 包数量
echo "总计 RPM 包数量: $(ls *.rpm | wc -l)"

# 5. 卸载 ISO(可选)
sudo umount /mnt/centos-iso

组织 RPM 包结构
#

# 创建标准的 YUM 仓库目录结构
mkdir -p /tmp/yum-upload/{7/os/x86_64,8/os/x86_64}

# 将 CentOS 7 的包放到对应目录
mv /tmp/centos7-rpms/*.rpm /tmp/yum-upload/7/os/x86_64/

# 添加自定义 RPM 包(如果有)
# cp /path/to/custom/*.rpm /tmp/yum-upload/7/os/x86_64/

第四步:批量上传 RPM 包
#

创建上传脚本
#

cat > /usr/local/bin/yum-upload.sh << 'EOF'
#!/bin/bash
# Yum 仓库 RPM 包批量上传脚本

set -e

# 配置变量
NEXUS_URL="http://nexus.example.com:8081"
REPOSITORY="yum-hosted"
USERNAME="admin"
PASSWORD="your-password"
RPM_DIR="/tmp/yum-upload"

# 安全提示
echo "⚠️  注意:此脚本将上传 RPM 包到 Nexus3"
echo "仓库: $REPOSITORY"
echo "目录: $RPM_DIR"
read -p "确认继续?(y/N): " confirm

if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
    echo "操作已取消"
    exit 0
fi

# 关闭命令历史记录(安全考虑)
set +H

# 统计信息
total_files=0
uploaded_files=0
failed_files=0

# 递归上传函数
upload_rpms() {
    local base_dir="$1"
    local relative_path="$2"

    for item in "$base_dir"/*; do
        if [[ -d "$item" ]]; then
            # 递归处理子目录
            local dirname=$(basename "$item")
            upload_rpms "$item" "$relative_path/$dirname"
        elif [[ -f "$item" && "$item" == *.rpm ]]; then
            # 上传 RPM 文件
            local filename=$(basename "$item")
            local upload_path="$relative_path/$filename"

            echo "上传: $upload_path"
            total_files=$((total_files + 1))

            if curl -f -u "$USERNAME:$PASSWORD" \
                    --upload-file "$item" \
                    "$NEXUS_URL/repository/$REPOSITORY$upload_path"; then
                uploaded_files=$((uploaded_files + 1))
                echo "✅ 成功: $filename"
            else
                failed_files=$((failed_files + 1))
                echo "❌ 失败: $filename"
            fi
        fi
    done
}

# 开始上传
echo "开始上传 RPM 包..."
upload_rpms "$RPM_DIR" ""

# 输出统计信息
echo ""
echo "上传完成!"
echo "总文件数: $total_files"
echo "成功上传: $uploaded_files"
echo "失败数量: $failed_files"

# 触发仓库索引重建
echo "触发仓库索引重建..."
curl -X POST -u "$USERNAME:$PASSWORD" \
     "$NEXUS_URL/service/rest/v1/repositories/$REPOSITORY/rebuild-index"

echo "✅ 索引重建已触发,请等待完成"
EOF

chmod +x /usr/local/bin/yum-upload.sh

执行上传
#

# 修改脚本中的配置信息
vim /usr/local/bin/yum-upload.sh

# 执行上传
/usr/local/bin/yum-upload.sh

手动上传示例
#

# 设置变量
NEXUS_URL="http://nexus.example.com:8081"
REPOSITORY="yum-hosted"
USERNAME="admin"
PASSWORD="your-password"

# 上传单个 RPM 包
curl -v -u "$USERNAME:$PASSWORD" \
     --upload-file /tmp/yum-upload/7/os/x86_64/vim-enhanced-7.4.629-8.el7_9.x86_64.rpm \
     "$NEXUS_URL/repository/$REPOSITORY/7/os/x86_64/vim-enhanced-7.4.629-8.el7_9.x86_64.rpm"

# 批量上传(简单版本)
cd /tmp/yum-upload/7/os/x86_64
for rpm in *.rpm; do
    echo "上传: $rpm"
    curl -f -u "$USERNAME:$PASSWORD" \
         --upload-file "$rpm" \
         "$NEXUS_URL/repository/$REPOSITORY/7/os/x86_64/$rpm"
done

第五步:重建仓库索引
#

上传完成后需要重建 YUM 仓库索引:

自动重建
#

# 通过 API 触发索引重建
curl -X POST -u admin:password \
     http://nexus.example.com:8081/service/rest/v1/repositories/yum-hosted/rebuild-index

手动重建
#

  1. 登录 Nexus3 管理界面
  2. 导航到仓库管理: RepositoryRepositories
  3. 选择 yum-hosted 仓库
  4. 点击 “Rebuild index” 按钮

重建索引操作

图:手动触发仓库索引重建

索引重建进度

图:索引重建任务的执行进度

第六步:客户端配置
#

配置 YUM 客户端
#

在需要使用私有仓库的 CentOS/RHEL 系统上配置:

# 1. 备份原有仓库配置
sudo mv /etc/yum.repos.d /etc/yum.repos.d.backup
sudo mkdir -p /etc/yum.repos.d

# 2. 创建 Nexus3 仓库配置
cat > /etc/yum.repos.d/nexus.repo << 'EOF'
[nexus-yum]
name=Nexus YUM Repository
baseurl=http://nexus.example.com:8081/repository/yum-hosted/$releasever/os/$basearch/
enabled=1
gpgcheck=0
priority=1
EOF

# 3. 清理并重建缓存
sudo yum clean all
sudo yum makecache

# 4. 验证仓库配置
yum repolist

高级配置选项
#

# 创建更完整的仓库配置
cat > /etc/yum.repos.d/nexus-complete.repo << 'EOF'
[nexus-base]
name=Nexus Base Repository
baseurl=http://nexus.example.com:8081/repository/yum-hosted/$releasever/os/$basearch/
enabled=1
gpgcheck=0
priority=1
metadata_expire=300
keepcache=1

[nexus-updates]
name=Nexus Updates Repository
baseurl=http://nexus.example.com:8081/repository/yum-updates/$releasever/os/$basearch/
enabled=1
gpgcheck=0
priority=2

[nexus-extras]
name=Nexus Extras Repository
baseurl=http://nexus.example.com:8081/repository/yum-extras/$releasever/os/$basearch/
enabled=0
gpgcheck=0
priority=3
EOF

测试安装
#

# 搜索可用包
yum search vim

# 安装软件包
sudo yum install -y vim-enhanced

# 查看包信息
yum info vim-enhanced

# 列出所有可用包
yum list available | head -20

YUM 客户端测试

图:YUM 客户端成功连接私有仓库的示例

故障排除
#

常见问题
#

问题可能原因解决方案
repomd.xml 不存在索引未重建手动触发索引重建
包下载失败路径深度配置错误检查 Repodata Depth 设置
权限被拒绝认证失败检查用户名密码和权限
仓库不可用网络连接问题检查网络和防火墙设置

调试命令
#

# 测试仓库连通性
curl -I http://nexus.example.com:8081/repository/yum-hosted/7/os/x86_64/repodata/repomd.xml

# 查看详细错误信息
yum --verbose install package-name

# 检查仓库配置
yum-config-manager --dump nexus-yum

# 清理缓存
sudo yum clean all && sudo yum makecache

Helm Chart 私有仓库配置
#

Helm Chart 私有仓库可以为 Kubernetes 应用提供统一的包管理服务,便于企业内部应用的分发和版本管理。

第一步:创建 Helm Blob 存储
#

配置 Blob Store
#

  1. 创建专用 Blob Store
    • Name: helm-blob
    • Path: helm

创建 Helm Blob 存储

图:创建 Helm 专用的 Blob 存储

第二步:创建 Helm Hosted 仓库
#

配置步骤
#

  1. 创建新仓库

    • 选择 helm (hosted)
  2. 配置仓库参数

参数说明
Namehelm-hosted仓库名称
Blob storehelm-blob使用创建的 Blob 存储
Deployment policyAllow redeploy允许重新部署

选择 Helm Hosted 类型

图:选择 Helm Hosted 仓库类型

Helm Hosted 基本配置

图:Helm Hosted 仓库的基本配置

Helm Hosted 存储配置

图:Helm Hosted 仓库的存储配置

Helm Hosted 完成配置

图:Helm Hosted 仓库配置完成

第三步:创建 Helm Proxy 仓库(可选)
#

虽然上面的截图中没有演示 Proxy 仓库配置,但在实际使用中,Proxy 仓库非常有用:

配置 Helm Proxy 仓库
#

# 常用的 Helm Chart 仓库地址
# 官方稳定仓库: https://charts.helm.sh/stable
# Bitnami 仓库: https://charts.bitnami.com/bitnami
# Prometheus 社区: https://prometheus-community.github.io/helm-charts
参数说明
Namehelm-proxy-stable仓库名称
Remote storagehttps://charts.helm.sh/stable远程仓库地址
Blob storehelm-blob使用相同的 Blob 存储

第四步:上传 Helm Charts
#

方法一:Web 界面上传
#

  1. 导航到仓库

    • 点击:Browse → 选择 helm-hosted
  2. 上传 Chart

    • 点击 Upload component
    • 选择 .tgz 格式的 Helm Chart 文件

Web 界面上传 Helm Chart

图:通过 Web 界面上传 Helm Chart

上传 Chart 文件

图:选择并上传 Helm Chart 文件

方法二:命令行上传
#

# 基本上传命令
curl -u "admin:password" \
     --upload-file ./my-chart-1.0.0.tgz \
     http://nexus.example.com:8081/repository/helm-hosted/

# 批量上传脚本
cat > /usr/local/bin/helm-upload.sh << 'EOF'
#!/bin/bash
# Helm Chart 批量上传脚本

NEXUS_URL="http://nexus.example.com:8081"
REPOSITORY="helm-hosted"
USERNAME="admin"
PASSWORD="your-password"
CHARTS_DIR="./charts"

if [[ ! -d "$CHARTS_DIR" ]]; then
    echo "错误: 目录 $CHARTS_DIR 不存在"
    exit 1
fi

echo "开始上传 Helm Charts..."

for chart in "$CHARTS_DIR"/*.tgz; do
    if [[ -f "$chart" ]]; then
        chart_name=$(basename "$chart")
        echo "上传: $chart_name"

        if curl -f -u "$USERNAME:$PASSWORD" \
                --upload-file "$chart" \
                "$NEXUS_URL/repository/$REPOSITORY/$chart_name"; then
            echo "✅ 成功: $chart_name"
        else
            echo "❌ 失败: $chart_name"
        fi
    fi
done

echo "上传完成!"
EOF

chmod +x /usr/local/bin/helm-upload.sh

方法三:使用 Helm 插件
#

# 安装 Helm push 插件
helm plugin install https://github.com/chartmuseum/helm-push

# 添加仓库
helm repo add nexus http://nexus.example.com:8081/repository/helm-hosted/ \
  --username admin --password your-password

# 推送 Chart
helm push my-chart-1.0.0.tgz nexus

第五步:客户端配置和使用
#

添加 Helm 仓库
#

# 添加私有仓库
helm repo add nexus-helm http://nexus.example.com:8081/repository/helm-hosted/

# 如果需要认证
helm repo add nexus-helm http://nexus.example.com:8081/repository/helm-hosted/ \
  --username admin --password your-password

# 更新仓库索引
helm repo update

# 验证仓库
helm repo list

搜索和安装 Charts
#

# 搜索可用的 Charts
helm search repo nexus-helm

# 查看 Chart 详情
helm show chart nexus-helm/my-chart

# 安装 Chart
helm install my-release nexus-helm/my-chart

# 升级 Chart
helm upgrade my-release nexus-helm/my-chart --version 1.1.0

开发和发布流程
#

# 1. 创建新的 Chart
helm create my-new-chart

# 2. 编辑 Chart 内容
# 修改 Chart.yaml, values.yaml, templates/ 等

# 3. 验证 Chart
helm lint my-new-chart/

# 4. 打包 Chart
helm package my-new-chart/

# 5. 上传到私有仓库
curl -u admin:password \
     --upload-file my-new-chart-1.0.0.tgz \
     http://nexus.example.com:8081/repository/helm-hosted/

# 6. 更新仓库索引
helm repo update

PyPI 私有仓库配置
#

PyPI 私有仓库可以为 Python 项目提供包管理服务,支持企业内部 Python 包的分发和版本管理。

第一步:创建 PyPI Blob 存储
#

配置 Blob Store
#

  1. 创建专用 Blob Store
    • Name: pypi-blob
    • Path: pypi

创建 PyPI Blob 存储

图:创建 PyPI 专用的 Blob 存储

第二步:创建 PyPI Hosted 仓库
#

配置步骤
#

  1. 创建新仓库

    • 选择 pypi (hosted)
  2. 配置仓库参数

参数说明
Namepypi-hosted仓库名称
Blob storepypi-blob使用创建的 Blob 存储
Deployment policyAllow redeploy允许重新部署

创建 PyPI Hosted 仓库

图:创建 PyPI Hosted 仓库配置

第三步:创建 PyPI Proxy 仓库
#

为了代理官方 PyPI 仓库,提供缓存和加速功能:

参数说明
Namepypi-proxy仓库名称
Remote storagehttps://pypi.org/PyPI 官方地址
Blob storepypi-blob使用相同的 Blob 存储

国内镜像源推荐:

  • 阿里云: https://mirrors.aliyun.com/pypi/simple/
  • 清华大学: https://pypi.tuna.tsinghua.edu.cn/simple/
  • 豆瓣: https://pypi.douban.com/simple/

第四步:创建 PyPI Group 仓库
#

Group 仓库将 hosted 和 proxy 仓库组合成统一入口:

创建 PyPI Group 仓库

图:创建 PyPI Group 仓库,组合多个仓库

配置 Group 仓库
#

参数说明
Namepypi-group仓库名称
Blob storepypi-blob使用相同的 Blob 存储
Member repositoriespypi-hosted, pypi-proxy包含的仓库

重要: 将 pypi-hosted 放在前面,确保内部包优先级更高。

PyPI Group 仓库地址

图:配置完成后使用 Group 仓库地址

第五步:上传 Python 包
#

方法一:使用 twine 上传
#

# 1. 安装 twine 工具
pip install twine

# 2. 构建 Python 包
python setup.py sdist bdist_wheel

# 3. 上传到私有仓库
twine upload --repository-url http://nexus.example.com:8081/repository/pypi-hosted/ \
             dist/* \
             --username admin \
             --password your-password

方法二:配置 .pypirc 文件
#

# 创建 .pypirc 配置文件
cat > ~/.pypirc << 'EOF'
[distutils]
index-servers =
    nexus
    nexus-hosted

[nexus]
repository = http://nexus.example.com:8081/repository/pypi-group/
username = admin
password = your-password

[nexus-hosted]
repository = http://nexus.example.com:8081/repository/pypi-hosted/
username = admin
password = your-password
EOF

# 设置文件权限
chmod 600 ~/.pypirc

# 使用配置文件上传
twine upload --repository nexus-hosted dist/*

方法三:批量上传脚本
#

cat > /usr/local/bin/pypi-upload.sh << 'EOF'
#!/bin/bash
# PyPI 包批量上传脚本

NEXUS_URL="http://nexus.example.com:8081/repository/pypi-hosted/"
USERNAME="admin"
PASSWORD="your-password"
DIST_DIR="./dist"

if [[ ! -d "$DIST_DIR" ]]; then
    echo "错误: 目录 $DIST_DIR 不存在"
    echo "请先运行: python setup.py sdist bdist_wheel"
    exit 1
fi

echo "开始上传 Python 包..."

# 上传所有 .tar.gz 和 .whl 文件
for package in "$DIST_DIR"/*.{tar.gz,whl}; do
    if [[ -f "$package" ]]; then
        package_name=$(basename "$package")
        echo "上传: $package_name"

        if twine upload --repository-url "$NEXUS_URL" \
                        --username "$USERNAME" \
                        --password "$PASSWORD" \
                        "$package"; then
            echo "✅ 成功: $package_name"
        else
            echo "❌ 失败: $package_name"
        fi
    fi
done

echo "上传完成!"
EOF

chmod +x /usr/local/bin/pypi-upload.sh

第六步:客户端配置
#

配置 pip 使用私有仓库
#

# 方法一:命令行指定
pip install --index-url http://nexus.example.com:8081/repository/pypi-group/simple/ \
            --trusted-host nexus.example.com \
            your-package

# 方法二:配置文件
mkdir -p ~/.pip
cat > ~/.pip/pip.conf << 'EOF'
[global]
index-url = http://nexus.example.com:8081/repository/pypi-group/simple/
trusted-host = nexus.example.com

[install]
trusted-host = nexus.example.com
EOF

配置认证(如果需要)
#

# 在 pip.conf 中添加认证信息
cat > ~/.pip/pip.conf << 'EOF'
[global]
index-url = http://admin:your-password@nexus.example.com:8081/repository/pypi-group/simple/
trusted-host = nexus.example.com
EOF

企业环境配置
#

# 创建企业级配置
sudo mkdir -p /etc/pip
sudo cat > /etc/pip/pip.conf << 'EOF'
[global]
index-url = http://nexus.example.com:8081/repository/pypi-group/simple/
trusted-host = nexus.example.com
timeout = 60

[install]
trusted-host = nexus.example.com
EOF

第七步:测试和验证
#

测试包安装
#

# 安装公共包(通过 proxy 仓库)
pip install requests

# 安装内部包(从 hosted 仓库)
pip install your-internal-package

# 查看包信息
pip show requests

# 列出已安装的包
pip list

验证仓库连通性
#

# 测试仓库访问
curl -I http://nexus.example.com:8081/repository/pypi-group/simple/

# 搜索包
pip search your-package-name

# 查看包的可用版本
pip index versions your-package-name

总结与最佳实践
#

部署总结
#

通过本文的详细指导,我们成功实现了:

完整的 Nexus3 部署: 从环境准备到服务启动的全流程 ✅ Docker 私有仓库: 支持镜像推送、拉取和管理 ✅ Nginx 反向代理: 提供统一访问入口和负载均衡 ✅ 版本升级方案: 安全可靠的升级和回滚策略 ✅ 多格式仓库支持: Yum、Helm、PyPI 等多种包管理格式 ✅ 企业级配置: 适用于生产环境的安全和性能配置

最佳实践建议
#

1. 安全性
#

  • 访问控制: 配置细粒度的用户权限和角色
  • 网络安全: 使用 HTTPS 和防火墙保护服务
  • 数据加密: 敏感数据传输和存储加密
  • 定期审计: 监控访问日志和异常行为

2. 性能优化
#

  • 资源配置: 根据使用量调整 JVM 内存和 CPU 资源
  • 存储优化: 使用 SSD 存储提高 I/O 性能
  • 网络优化: 配置 CDN 和缓存策略
  • 清理策略: 定期清理过期和未使用的制品

3. 运维管理
#

  • 监控告警: 配置系统监控和告警机制
  • 备份策略: 实施定期数据备份和恢复测试
  • 文档维护: 保持部署和配置文档的更新
  • 团队培训: 确保团队成员熟悉操作流程

4. 扩展规划
#

  • 高可用部署: 考虑集群部署和故障转移
  • 容量规划: 根据业务增长规划存储和带宽
  • 集成开发: 与 CI/CD 流水线深度集成
  • 多环境管理: 为不同环境配置独立的仓库

常用维护命令
#

# 系统监控
docker stats nexus3
df -h /application/nexus3/data
netstat -tlnp | grep -E "8081|8082|8083"

# 日志查看
docker logs -f nexus3
tail -f /var/log/nginx/nexus.example.com.log

# 备份操作
tar -czf nexus3-backup-$(date +%Y%m%d).tar.gz /application/nexus3/data

# 清理操作
docker system prune -f
find /application/nexus3/data -name "*.tmp" -delete

技术支持资源
#

通过本指南,您已经掌握了 Nexus3 的完整部署和管理技能,可以为企业构建一个稳定、安全、高效的制品管理平台。在实际使用过程中,请根据具体需求调整配置参数,并持续关注官方更新和安全公告。

相关文章

Docker 部署 OpenLDAP 统一身份认证服务
·2305 字·11 分钟
DevOps Openldap Docker Authentication Devops
使用 Docker 快速部署 Redis 服务器
·259 字·2 分钟
Docker Redis Centos7 Docker
Kind 部署本地k8s集群的使用记录
·238 字·2 分钟
Kubernetes Docker DevOps Centos7 Kind