【Devops】Nexus实践【持续施工中】

135 阅读2分钟

官网地址:www.sonatype.com

一、安装

docker compose:

version: '3'
services:
  nexus:
    image: sonatype/nexus3:latest
    container_name: nexus
    ports:
      - "8081:8081"
      - "8082:8082"
      - "8083:8083"
    environment:
      - INSTALL4J_ADD_VM_PARAMS=-Xms2g -Xmx2g -XX:MaxDirectMemorySize=3g  # 内存配置
    volumes:
      - /opt/nexus/data:/nexus-data   [本机路径:容器路径]
    restart: always

二进制安装:

官网地址 help.sonatype.com/en/download…

1.将对应操作系统的连接复制,然后下载到服务器上,此处以及下文均以debian12为例:

wget https://download.sonatype.com/nexus/3/nexus-3.77.1-01-unix.tar.gz

2.解压

tar -zvxf nexus-3.77.1-01-unix.tar.gz

解压后有两个文件夹

nexus-3.77.1-01 运行时数据

sonatype-work 数据和配置文件

  1. 创建执行用户,并且赋予其文件的权限,该用户需要有nexus-3.77.1-01的执行权限以及sonatype-work的读写权限

adduser nexus

addgroup nexus

chown -R nexus:nexus [file]

  1. 修改启动配置

其文件通常在 运行时文件的nexus-3.77.1-01/bin/nexus.rc下,将对应的用户改为刚刚新建的用户即可,此处为nexus

二、其它环境以及启动

jdk安装apt install openjdk-17-jre-headless

启动:nexus-3.77.1-01/bin/nexus start

验证:ps aux | grep nexus

默认密码:cat cat ./sonatype-work/nexus3/admin.password        [账号为:root]

三、新建用户

1.登录后,点击设置面板,然后选择角色,新建角色

image.png

2.填写信息,并赋予权限

image.png

3.新建用户

image.png

四、上传构建

Gradle项目配置 版本8.1.1

应用发布插件

plugins {
    val kotlinVersion = "1.9.24"
    `maven-publish`
}

subprojects {
    apply(plugin = "maven-publish")
}

打包函数

此处我使用的是单体六边形架构,涉及到多模块。因为额外有一个打包任务

tasks.register("packageAll") {
    group = "build"
    description = "Package all modules with environment specific configurations"
    dependsOn(":apis:bootJar")

    doLast {
        // 清理和创建发布目录
        delete("$rootDir/build/dist")
        mkdir("$rootDir/build/dist")
        mkdir("$rootDir/build/dist/config")

        // 复制主应用jar
        copy {
            from("${project(":apis").buildDir}/libs/jxzgParkService.jar")
            into("$rootDir/build/dist")
        }

        // 复制基础配置文件
        copy {
            from("${project(":apis").projectDir}/src/main/resources") {
                include("application.properties")
            }
            into("$rootDir/build/dist/config")
        }

        // 复制对应环境的配置文件
        subprojects.forEach { subproject ->
            copy {
                from("${subproject.projectDir}/src/main/resources") {
                    include("*-${targetEnv}.properties")
                }
                into("$rootDir/build/dist/config")
                duplicatesStrategy = DuplicatesStrategy.EXCLUDE
            }
        }

        // 创建启动脚本
        file("$rootDir/build/dist/start.sh").writeText("""
            #!/bin/bash
            
            # JVM参数
            JAVA_OPTS="-server -Xms1g -Xmx1g"
            
            # 启动命令
            java ${'$'}JAVA_OPTS -jar jxzgParkService.jar \
                --spring.profiles.active=${targetEnv} \
                --spring.config.location=file:./config/
        """.trimIndent())

        // 设置执行权限
        file("$rootDir/build/dist/start.sh").setExecutable(true)

        // 打印构建信息
        println("\n打包完成 (环境: $targetEnv)")
        file("$rootDir/build/dist/jxzgParkService.jar").let { jarFile ->
            println("- JAR: ${jarFile.name} (${jarFile.length() / 1024 / 1024}MB)")
            println("- 位置: ${jarFile.absolutePath}")
        }
    }
}

构建完成后,jar会在xxxxxxxxxx\apis\build\libs下

配置发布插件

publishing {
    publications {
        create<MavenPublication>("maven") {
            artifact("${project(":apis").buildDir}/libs/jxzgParkService.jar") {
                extension = "jar"
            }
            // 或者使用相对路径
            // artifact("apis/build/libs/apis.jar")

            groupId = "com.xxxx.devops"
            artifactId = "jxzgParkService"
            version = project.version.toString()
        }
    }

    repositories {
        maven {
            name = "nexus"
            url = uri("http://xxxxxxxxxxxx/repository/maven-snapshots/")
            isAllowInsecureProtocol = true
            credentials {
                username = project.findProperty("repoUser") as String? ?: System.getenv("NEXUS_USERNAME")
                password = project.findProperty("repoPassword") as String? ?: System.getenv("NEXUS_PASSWORD")
            }
        }
    }
}

上述username/password,在项目根目录下的gradle.properties文件中

效果: 使用gradle publish,即可发布

五、RestFul API

查看存储库

nexus@nexus:/opt$ curl -v -u name:passwd -X GET 'http://192.168.44.200:8081/service/rest/v1/repositories'
Note: Unnecessary use of -X or --request, GET is already inferred.
*   Trying 192.168.44.200:8081...
* Connected to 192.168.44.200 (192.168.44.200) port 8081 (#0)
* Server auth using Basic with user 'devops-m'
> GET /service/rest/v1/repositories HTTP/1.1
> Host: 192.168.44.200:8081
> Authorization: Basic ZGV2b3BzLW06YmpzdEAxMjM0IQ==
> User-Agent: curl/7.88.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Mon, 17 Feb 2025 09:19:51 GMT
< Server: Nexus/3.77.1-01 (COMMUNITY)
< X-Content-Type-Options: nosniff
< Content-Type: application/json
< Content-Length: 169
< 
[ {
  "name" : "maven-snapshots",
  "format" : "maven2",
  "type" : "hosted",
  "url" : "http://192.168.44.200:8081/repository/maven-snapshots",
  "attributes" : { }
* Connection #0 to host 192.168.44.200 left intact
} ]

查看存储库内容

curl -v -u name:passwd -X GET 'http://192.168.44.200:8081/service/rest/v1/components?repository=maven-snapshots'

【由于内容过长,因此不做展示了】

六、blob库

可使用本机存储,或者使用s3 api的存储库

七、清理政策

image.png

此功能用于删除已有构件

image.png

设置完成后,将其与对应的库绑定

在system下的tasks中,可以查看任务计划:

image.png

可以使用 上传/删除任务与压缩任务联动【compact blob store】