# 私有 Maven 仓库解决方案：自建 Nexus 实施指南

---

## 一、方案选择

### 1.1 当前项目评估

| 维度        | 当前状态                   | 影响分析            |
|-----------|------------------------|-----------------|
| **项目阶段**  | 测试验证阶段                 | 代码测试、修复验证、可行性验证 |
| **服务器用途** | 测试环境                   | 资源配置可适度降低       |
| **项目规模**  | 单项目，微服务 12+ 个          | 需要高效的依赖管理       |
| **团队规模**  | 小型团队                   | 运维成本可控          |
| **基础设施**  | 阿里云 ECS（8核16GB，80GB磁盘） | 资源充足，适合测试       |
| **容器技术**  | 使用 Podman（Docker不稳定）   | 需要适配 Podman 部署  |

### 1.2 方案对比与选择

基于测试环境需求，**选择方案 A：自建 Nexus**

| 方案              | 优势                 | 劣势       | 适用场景       |
|-----------------|--------------------|----------|------------|
| **自建 Nexus**    | 自主可控、内网高速、低成本、适合测试 | 需要基础运维   | 测试环境、中小型团队 |
| **云效 Packages** | 免运维、SaaS服务         | 外网依赖、有成本 | 生产环境、大型团队  |

### 1.3 架构设计（测试环境）

```
┌─────────────────────────────────────────────────────────────────┐
│                阿里云 ECS - 测试环境                            │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────┐    ┌─────────────┐    ┌───────────────────┐  │
│  │  Jenkins    │───▶│   Nexus     │◀───│  测试容器集群    │  │
│  │  (构建测试)  │    │  (私服)     │    │  (运行测试)      │  │
│  └─────────────┘    └─────────────┘    └───────────────────┘  │
│        │                  │                                    │
│        ▼                  ▼                                    │
│  ┌─────────────┐    ┌─────────────┐                            │
│  │ 测试报告    │    │ 依赖缓存    │                            │
│  │ (验证修复)  │    │ (加速构建)   │                            │
│  └─────────────┘    └─────────────┘                            │
└─────────────────────────────────────────────────────────────────┘
```

---

## 二、部署实施（测试环境优化版）

### 2.1 服务器准备

**测试环境配置**：

- ECS 规格：8核 16GB（分配 2核4GB 给 Nexus）
- 磁盘：总容量 80GB（分配 20GB 给 Nexus 数据）
- 网络：与 Jenkins、测试容器同区域内网
- 操作系统：Linux（支持 Podman）

### 2.2 Podman 部署 Nexus（测试环境配置）

```bash
# 创建数据目录（使用项目统一的数据目录结构）
mkdir -p /opt/fzx/nexus/data && chown -R 200:200 /opt/fzx/nexus/data

# 启动 Nexus（测试环境配置，资源适度）
podman run -d \
  --name fzx-nexus \
  -p 8081:8081 \
  -v /opt/fzx/nexus/data:/nexus-data \
  --restart=always \
  --network=fzx-network \
  --ip=172.20.0.200 \
  --memory=4G \
  --cpus=2 \
  sonatype/nexus3:3.67.0
```

**参数说明（测试环境优化）**：
| 参数 | 说明 | 测试环境配置 |
|------|------|--------------|
| `--name fzx-nexus` | 容器名称 | 与项目命名规范一致 |
| `-p 8081:8081` | Web UI 端口 | 仅开放必要端口 |
| `-v /opt/fzx/nexus/data:/nexus-data` | 数据持久化 | 使用项目统一目录 |
| `--network=fzx-network` | 统一网络 | 便于测试容器访问 |
| `--ip=172.20.0.200` | 固定IP | 便于 Jenkins 访问 |
| `--memory=4G` | 内存限制 | 测试环境适度分配 |
| `--cpus=2` | CPU限制 | 测试环境适度分配 |

### 2.3 初始配置

1. **访问地址**：`http://<ECS_IP>:8081`
2. **初始密码**：
   ```bash
   podman exec fzx-nexus cat /nexus-data/admin.password
   ```
3. **登录后修改密码**并配置仓库

### 2.4 仓库配置（测试环境）

创建以下仓库：

| 仓库名称                 | 类型     | 用途        | URL                                          |
|----------------------|--------|-----------|----------------------------------------------|
| `maven-releases`     | hosted | 存放正式发布包   | -                                            |
| `maven-snapshots`    | hosted | 存放开发快照包   | -                                            |
| `maven-aliyun-proxy` | proxy  | 代理阿里云公共仓库 | `https://maven.aliyun.com/repository/public` |
| `maven-public`       | group  | 聚合仓库      | 包含以上三个仓库                                     |

---

## 三、Maven 配置

### 3.1 Jenkins 服务器 settings.xml

> **安全说明**：禁止硬编码凭证，使用 Jenkins 凭证管理注入变量。

更新项目中的 settings.xml：

```xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">

    <mirrors>
        <mirror>
            <id>nexus</id>
            <mirrorOf>central</mirrorOf>
            <url>http://172.20.0.200:8081/repository/maven-public/</url>
        </mirror>
    </mirrors>

    <servers>
        <server>
            <id>nexus-releases</id>
            <username>${nexus.username}</username>
            <password>${nexus.password}</password>
        </server>
        <server>
            <id>nexus-snapshots</id>
            <username>${nexus.username}</username>
            <password>${nexus.password}</password>
        </server>
    </servers>

    <profiles>
        <profile>
            <id>nexus</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <repositories>
                <repository>
                    <id>nexus-releases</id>
                    <url>http://172.20.0.200:8081/repository/maven-releases/</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>false</enabled></snapshots>
                </repository>
                <repository>
                    <id>nexus-snapshots</id>
                    <url>http://172.20.0.200:8081/repository/maven-snapshots/</url>
                    <releases><enabled>false</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </repository>
            </repositories>
        </profile>
    </profiles>

</settings>
```

### 3.2 项目根 pom.xml 配置

```xml
<distributionManagement>
    <repository>
        <id>nexus-releases</id>
        <name>Nexus Releases</name>
        <url>http://172.20.0.200:8081/repository/maven-releases/</url>
    </repository>
    <snapshotRepository>
        <id>nexus-snapshots</id>
        <name>Nexus Snapshots</name>
        <url>http://172.20.0.200:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>
```

---

## 四、测试环境 Jenkins Pipeline 集成

### 4.1 测试构建流程

```groovy
stage('Build Backend') {
    steps {
        script {
            def mavenRepo = "${env.WORKSPACE}/.m2/repository"
            def settingsFile = "${env.WORKSPACE}/infrastructure/jenkins/settings.xml"
            def testArg = params.SKIP_TESTS ? '-DskipTests' : ''
            def nexusUrl = 'http://172.20.0.200:8081'

            // 从Jenkins凭证管理获取Nexus认证信息（大厂标准）
            def nexusCredentials = credentials('nexus-credentials')
            def nexusUsername = nexusCredentials.username
            def nexusPassword = nexusCredentials.password

            echo "📦 测试构建参数"
            echo "  - Maven仓库: ${mavenRepo}"
            echo "  - Settings文件: ${settingsFile}"
            echo "  - Nexus地址: ${nexusUrl}"

            // 检查 Nexus 服务状态（测试环境可选）
            echo "🔍 检查 Nexus 服务状态"
            try {
                def response = httpRequest(url: "${nexusUrl}/service/rest/v1/status", timeout: 10)
                if (response.status == 200) {
                    echo "✅ Nexus 服务正常"
                } else {
                    echo "⚠️ Nexus 服务异常，尝试使用本地仓库"
                }
            } catch (Exception e) {
                echo "⚠️ Nexus 服务不可达，使用本地仓库构建"
            }

            // 1. 构建根项目（传递凭证变量）
            echo "📦 构建根项目"
            sh "mvn clean install ${testArg} -N -Dmaven.repo.local=${mavenRepo} -s ${settingsFile} -Dnexus.username=${nexusUsername} -Dnexus.password=${nexusPassword}"

            // 2. 构建 common-service 并推送到 Nexus
            dir("services/common-service") {
                echo "📦 构建并部署 common-service"
                sh "mvn clean deploy ${testArg} -Dmaven.repo.local=${mavenRepo} -s ${settingsFile} -Dnexus.username=${nexusUsername} -Dnexus.password=${nexusPassword}"
            }

            // 3. 构建其他业务服务
            def services = ['api-gateway', 'auth-service', 'user-service',
                           'order-service', 'merchant-service', 'platform-service',
                           'product-service', 'rider-service', 'upload-service',
                           'marketing-service', 'map-service']

            services.each { service ->
                dir("services/${service}") {
                    echo "📦 构建 ${service}"
                    sh "mvn clean package ${testArg} -Dmaven.repo.local=${mavenRepo} -s ${settingsFile} -Dnexus.username=${nexusUsername} -Dnexus.password=${nexusPassword}"
                }
            }

            echo "✅ 测试构建完成"
        }
    }
}
```

### 4.2 测试环境依赖管理策略

| 阶段           | 操作               | 说明               |
|--------------|------------------|------------------|
| **拉取代码**     | git checkout     | 获取测试分支代码         |
| **检查 Nexus** | HTTP 请求          | 测试环境可选，失败降级到本地仓库 |
| **本地安装**     | `mvn install -N` | 安装父 POM          |
| **公共模块**     | `mvn deploy`     | 推送到 Nexus 供测试使用  |
| **业务服务**     | `mvn package`    | 从 Nexus 拉取依赖     |

### 4.3 Jenkins 凭证配置（大厂标准）

> **安全最佳实践**：禁止在配置文件中硬编码敏感信息，必须使用 Jenkins 凭证管理。

#### 4.3.1 创建 Jenkins 凭证

1. 登录 Jenkins → 点击左侧菜单 `Credentials` → `System` → `Global credentials (unrestricted)`
2. 点击 `Add Credentials`
3. 选择 `Username with password` 类型
4. 填写：
  - **Username**: `admin`
  - **Password**: `Nexus@Test2026`
  - **ID**: `nexus-credentials`（必须与此ID一致）
  - **Description**: `Nexus Maven Repository Credentials`
5. 点击 `OK`

#### 4.3.2 安全说明

| 措施     | 说明             | 合规性        |
|--------|----------------|------------|
| 凭证加密存储 | Jenkins 内置加密机制 | ✅ 符合安全规范   |
| 权限控制   | 仅授权用户可查看/修改    | ✅ 符合最小权限原则 |
| 审计日志   | 记录凭证使用记录       | ✅ 符合审计要求   |

---

## 五、测试环境运维

### 5.1 日常运维（测试环境简化版）

```bash
# 查看 Nexus 日志
podman logs -f fzx-nexus

# 查看容器状态
podman ps -a | grep nexus

# 重启 Nexus（测试环境常用）
podman restart fzx-nexus

# 备份数据（测试环境可选）
tar -czvf /opt/fzx/backup/nexus-backup-$(date +%Y%m%d).tar.gz /opt/fzx/nexus/data

# 清理测试快照（定期清理）
# 在 Nexus UI 中配置清理策略
```

### 5.2 测试环境安全配置

| 措施     | 说明    | 测试环境配置                  |
|--------|-------|-------------------------|
| **密码** | 管理员密码 | 设置测试环境专用密码              |
| **网络** | 访问控制  | 使用项目统一网络                |
| **备份** | 数据备份  | 每日备份到 `/opt/fzx/backup` |

### 5.3 Podman 网络配置

```bash
# 检查 fzx-network 是否存在
podman network inspect fzx-network

# 如果不存在，创建网络
podman network create fzx-network --subnet=172.20.0.0/16 --gateway=172.20.0.1
```

---

## 六、测试环境故障处理

### 6.1 常见问题

| 问题         | 原因        | 解决方案                   |
|------------|-----------|------------------------|
| **依赖下载失败** | Nexus 未启动 | 检查 Nexus 状态或使用本地仓库     |
| **权限拒绝**   | 凭证错误      | 检查 settings.xml 配置     |
| **版本冲突**   | 缓存问题      | `mvn clean install -U` |
| **空间不足**   | 数据目录满     | 清理旧快照                  |

### 6.2 测试环境快速恢复

```bash
# 临时使用本地仓库构建
mvn clean install -DskipTests -o

# 重启 Nexus
podman restart fzx-nexus
```

---

## 七、测试环境特点总结

### 7.1 测试环境配置特点

| 维度       | 测试环境配置 | 说明              |
|----------|--------|-----------------|
| **资源分配** | 2核4GB  | 适度分配，节省资源用于其他测试 |
| **磁盘分配** | 20GB   | 满足测试需求即可        |
| **备份策略** | 每日备份   | 可选，根据测试重要性调整    |
| **安全配置** | 基础安全   | 测试环境可适度简化       |
| **降级策略** | 支持本地仓库 | Nexus不可用时自动降级   |

### 7.2 测试环境优势

| 优势         | 说明            |
|------------|---------------|
| **加速测试构建** | 内网依赖缓存，提升测试效率 |
| **支持代码修复** | 快速验证修复效果      |
| **验证可行性**  | 完整测试依赖管理流程    |
| **资源节省**   | 适度配置，不浪费资源    |

---

## 八、配置一致性校验（新增）

### 8.1 配置文件一致性检查

确保以下配置文件中的 Nexus 地址完全一致：

| 文件路径                                  | 配置项                        | 正确值                                        |
|---------------------------------------|----------------------------|--------------------------------------------|
| `infrastructure/jenkins/settings.xml` | 所有 `<url>` 节点              | `http://172.20.0.200:8081/repository/xxx/` |
| `infrastructure/jenkins/Jenkinsfile`  | `nexusUrl` 变量              | `http://172.20.0.200:8081`                 |
| `backend/pom.xml`                     | `<distributionManagement>` | `http://172.20.0.200:8081/repository/xxx/` |

### 8.2 检查命令

```bash
# 检查settings.xml中的Nexus地址
grep -n "172.20.0.200" infrastructure/jenkins/settings.xml

# 检查Jenkinsfile中的Nexus地址
grep -n "nexusUrl" infrastructure/jenkins/Jenkinsfile

# 检查pom.xml中的Nexus地址
grep -n "172.20.0.200" backend/pom.xml
```

✅ 所有输出应显示 `172.20.0.200:8081`，无 `8.140.221.49:8091` 出现。

### 8.3 安全检查清单

| 检查项                | 状态 | 说明                                    |
|--------------------|----|---------------------------------------|
| Jenkins凭证已创建       | ⬜  | 凭证ID: `nexus-credentials`             |
| settings.xml无硬编码密码 | ⬜  | 使用 `${nexus.username/password}`       |
| Jenkinsfile使用凭证管理  | ⬜  | 使用 `credentials('nexus-credentials')` |

---

**文档版本**：v2.2（测试环境优化版）
**更新日期**：2026-06-01
**适用项目**：风七六本地生活服务平台（测试环境）
**容器运行时**：Podman
