Nexus3 是世界领先的企业级制品仓库管理平台,为现代 DevOps 工具链提供统一的制品管理解决方案。本指南将从基础部署到企业级配置,全面介绍 Nexus3 的部署、配置、管理和运维最佳实践。
Nexus3 平台简介#
什么是 Nexus3#
Nexus Repository Manager 3 是由 Sonatype 公司开发的下一代制品仓库管理平台,作为 DevOps 工具链的核心组件,为软件开发生命周期提供统一的制品管理能力。
核心特性#
- 统一制品管理:支持 20+ 种包格式的统一管理
- 高性能架构:基于现代化架构设计,支持大规模并发访问
- 企业级安全:细粒度权限控制、LDAP 集成、漏洞扫描
- 智能代理:缓存外部仓库,提供离线访问能力
- REST API:完整的 API 支持,便于自动化集成
- 可扩展性:支持集群部署和水平扩展
支持的制品格式#
| 类别 | 格式 | 用途 |
|---|---|---|
| Java 生态 | Maven, Gradle | Java 项目依赖管理 |
| 前端生态 | 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 仓库(代理仓库)#
用途: 代理外部公共仓库,提供缓存和加速功能 工作原理:
- 客户端请求依赖包
- 如果本地缓存存在,直接返回
- 如果本地不存在,从远程仓库下载并缓存
- 后续相同请求直接从缓存返回

优势:
- 提高下载速度
- 减少外网带宽消耗
- 提供离线访问能力
- 统一管理外部依赖
3. Group 仓库(组合仓库)#
用途: 将多个仓库组合成一个统一的访问入口 特点:
- 可以包含 hosted、proxy、group 类型的仓库
- 支持优先级设置
- 提供统一的访问地址
重要提示: Group 仓库采用自上而下的匹配策略,一旦找到匹配的制品就停止搜索。因此,仓库的排序非常重要:

在上图示例中,如果 custom 和 aliyun 仓库都包含 centos:7 镜像,客户端拉取时会优先获取 custom 仓库中的版本。
环境准备#
系统要求#
硬件要求#
| 环境类型 | CPU | 内存 | 存储 | 网络 |
|---|---|---|---|---|
| 开发环境 | 4 核 | 8GB | 100GB | 1Gbps |
| 测试环境 | 8 核 | 16GB | 500GB | 1Gbps |
| 生产环境 | 16 核 | 32GB+ | 2TB+ | 10Gbps |
| 大型企业 | 32 核 | 64GB+ | 10TB+ | 10Gbps |
软件要求#
| 组件 | 最低版本 | 推荐版本 | 说明 |
|---|---|---|---|
| 操作系统 | CentOS 7.6 | CentOS 8+ / Ubuntu 20.04+ | 64位系统 |
| Docker | 19.03.0 | 20.10.0+ | 容器运行时 |
| Docker Compose | 1.25.0 | 1.29.0+ | 容器编排工具 |
| Java | OpenJDK 8 | OpenJDK 11+ | Nexus3 运行环境 |
网络端口规划#
| 端口 | 协议 | 服务 | 说明 |
|---|---|---|---|
| 8081 | TCP | Web UI | 管理界面和 REST API |
| 8082 | TCP | Docker Pull | Docker 镜像拉取 |
| 8083 | TCP | Docker Push | Docker 镜像推送 |
| 8084-8090 | TCP | Custom Repos | 自定义仓库端口 |
| 5432 | TCP | PostgreSQL | 外部数据库(可选) |
环境检查脚本#
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 界面初始化#
- 访问管理界面:
http://your-server-ip:8081 - 登录系统:
- 用户名:
admin - 密码:使用上面获取的初始密码
- 用户名:
- 完成设置向导:
- 修改管理员密码
- 配置匿名访问权限
- 选择改进计划参与方式

图: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 集成
- 智能代理:缓存外部仓库,提供离线访问能力
- 可扩展性:支持集群部署和水平扩展
运维优势#
- 容器化部署:标准化部署流程,环境一致性好
- 自动化备份:完整的备份恢复策略
- 监控告警:全面的监控和告警体系
- 故障排除:完善的诊断和恢复机制
最佳实践#
生产环境建议#
- 资源规划:根据制品数量和用户规模合理规划资源
- 安全配置:启用 HTTPS、配置防火墙、定期安全审计
- 备份策略:建立完善的备份和灾难恢复计划
- 监控告警:部署全面的监控和告警体系
- 性能调优:根据使用情况持续优化 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 存储#
登录 Nexus3 管理界面
- 访问:
http://your-server:8081 - 使用管理员账户登录
- 访问:
导航到 Blob Stores
- 点击左侧菜单:
Repository→Blob Stores
- 点击左侧菜单:
创建新的 Blob Store
- 点击
Create Blob Store - 选择
File类型 - 配置参数:
- 点击
| 参数 | 值 | 说明 |
|---|---|---|
| Name | docker-blob | Blob 存储名称 |
| Path | docker | 存储路径(相对于 nexus-data) |

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

图:Blob 存储的详细配置参数
第二步:创建 Docker Hosted 仓库#
Hosted 仓库用于存储企业内部构建的 Docker 镜像。
配置步骤#
导航到仓库管理
- 点击:
Repository→Repositories
- 点击:
创建新仓库
- 点击
Create repository - 选择
docker (hosted)
- 点击
配置 Hosted 仓库参数
| 参数 | 值 | 说明 |
|---|---|---|
| Name | docker-hosted | 仓库名称 |
| HTTP Port | 8083 | 推送端口 |
| Enable Docker V1 API | ☑️ | 支持 Docker V1 API |
| Blob store | docker-blob | 使用前面创建的 Blob 存储 |
| Deployment policy | Allow redeploy | 允许重新部署 |

图:选择 Docker Hosted 仓库类型

图:Docker Hosted 仓库的基本配置

图:Docker Hosted 仓库的高级配置选项
第三步:创建 Docker Proxy 仓库#
Proxy 仓库用于代理外部的 Docker 镜像仓库,提供缓存和加速功能。
配置步骤#
创建 Proxy 仓库
- 选择
docker (proxy)
- 选择
配置 Proxy 仓库参数
| 参数 | 值 | 说明 |
|---|---|---|
| Name | docker-proxy | 仓库名称 |
| HTTP Port | 8082 | 拉取端口 |
| Remote storage | https://registry-1.docker.io | Docker Hub 官方地址 |
| Docker Index | Use Docker Hub | 使用 Docker Hub 索引 |
| Blob store | docker-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 Group 仓库#
Group 仓库将多个仓库组合成一个统一的访问入口。
配置步骤#
创建 Group 仓库
- 选择
docker (group)
- 选择
配置 Group 仓库参数
| 参数 | 值 | 说明 |
|---|---|---|
| Name | docker-group | 仓库名称 |
| HTTP Port | 8082 | 统一访问端口 |
| Blob store | docker-blob | 使用相同的 Blob 存储 |
| Member repositories | docker-hosted, docker-proxy | 包含的仓库 |
重要提示: 仓库的顺序决定了查找优先级,建议将 docker-hosted 放在前面。

图:选择 Docker Group 仓库类型

图:Docker Group 仓库的成员配置
第五步:启用 Docker Bearer Token#
Docker 仓库需要启用 Bearer Token 认证才能正常工作。
配置步骤#
导航到安全设置
- 点击:
Security→Realms
- 点击:
启用 Docker Bearer Token Realm
- 将
Docker Bearer Token Realm从左侧移动到右侧 - 点击
Save保存配置
- 将

图:安全域配置界面

图:启用 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 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 authority | SSL 证书问题 | 添加到 insecure-registries 或配置正确的证书 |
dial tcp: lookup docker.example.com: no such host | DNS 解析失败 | 检查 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#
导航到 Blob Stores
- 点击:
Repository→Blob Stores
- 点击:
创建新的 Blob Store
- 点击
Create Blob Store - 配置参数:
- 点击
| 参数 | 值 | 说明 |
|---|---|---|
| Type | File | 文件存储类型 |
| Name | yum-blob | Blob 存储名称 |
| Path | yum | 存储路径 |

图:创建 Yum 专用的 Blob 存储

图:Yum Blob 存储的详细配置
第二步:创建 Yum Hosted 仓库#
配置 Hosted 仓库#
创建新仓库
- 点击:
Repository→Repositories→Create repository - 选择
yum (hosted)
- 点击:
配置仓库参数
| 参数 | 值 | 说明 |
|---|---|---|
| Name | yum-hosted | 仓库名称 |
| Blob store | yum-blob | 使用创建的 Blob 存储 |
| Deployment policy | Allow redeploy | 允许重新部署 |
| Repodata Depth | 3 | 重要: 仓库数据深度 |

图:选择 Yum Hosted 仓库类型

图:Yum Hosted 仓库的详细配置
重要配置说明#
**Repodata Depth(仓库数据深度)**是 Yum 仓库的关键配置:

图:官方文档中关于 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
手动重建#
- 登录 Nexus3 管理界面
- 导航到仓库管理:
Repository→Repositories - 选择 yum-hosted 仓库
- 点击 “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 客户端成功连接私有仓库的示例
故障排除#
常见问题#
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
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#
- 创建专用 Blob Store
- Name:
helm-blob - Path:
helm
- Name:

图:创建 Helm 专用的 Blob 存储
第二步:创建 Helm Hosted 仓库#
配置步骤#
创建新仓库
- 选择
helm (hosted)
- 选择
配置仓库参数
| 参数 | 值 | 说明 |
|---|---|---|
| Name | helm-hosted | 仓库名称 |
| Blob store | helm-blob | 使用创建的 Blob 存储 |
| Deployment policy | Allow redeploy | 允许重新部署 |

图:选择 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
| 参数 | 值 | 说明 |
|---|---|---|
| Name | helm-proxy-stable | 仓库名称 |
| Remote storage | https://charts.helm.sh/stable | 远程仓库地址 |
| Blob store | helm-blob | 使用相同的 Blob 存储 |
第四步:上传 Helm Charts#
方法一:Web 界面上传#
导航到仓库
- 点击:
Browse→ 选择helm-hosted
- 点击:
上传 Chart
- 点击
Upload component - 选择
.tgz格式的 Helm Chart 文件
- 点击

图:通过 Web 界面上传 Helm 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#
- 创建专用 Blob Store
- Name:
pypi-blob - Path:
pypi
- Name:

图:创建 PyPI 专用的 Blob 存储
第二步:创建 PyPI Hosted 仓库#
配置步骤#
创建新仓库
- 选择
pypi (hosted)
- 选择
配置仓库参数
| 参数 | 值 | 说明 |
|---|---|---|
| Name | pypi-hosted | 仓库名称 |
| Blob store | pypi-blob | 使用创建的 Blob 存储 |
| Deployment policy | Allow redeploy | 允许重新部署 |

图:创建 PyPI Hosted 仓库配置
第三步:创建 PyPI Proxy 仓库#
为了代理官方 PyPI 仓库,提供缓存和加速功能:
| 参数 | 值 | 说明 |
|---|---|---|
| Name | pypi-proxy | 仓库名称 |
| Remote storage | https://pypi.org/ | PyPI 官方地址 |
| Blob store | pypi-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 仓库,组合多个仓库
配置 Group 仓库#
| 参数 | 值 | 说明 |
|---|---|---|
| Name | pypi-group | 仓库名称 |
| Blob store | pypi-blob | 使用相同的 Blob 存储 |
| Member repositories | pypi-hosted, pypi-proxy | 包含的仓库 |
重要: 将 pypi-hosted 放在前面,确保内部包优先级更高。

图:配置完成后使用 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
技术支持资源#
- 官方文档: Nexus Repository Manager 3
- 社区论坛: Sonatype Community
- GitHub 仓库: nexus-public
- Docker Hub: sonatype/nexus3
通过本指南,您已经掌握了 Nexus3 的完整部署和管理技能,可以为企业构建一个稳定、安全、高效的制品管理平台。在实际使用过程中,请根据具体需求调整配置参数,并持续关注官方更新和安全公告。
