Nexus Repository

Nexus Repository

들어가며

Nexus Repository란 무엇인가 한 문장으로 말하면 사내 공용 부품 창고입니다. 개발할 때 쓰는 라이브러리, 패키지, 도커 이미지 같은 것들을 한곳에 모아두고 필요할 때 꺼내 쓰도록 관리해 주는 서버입니다.

지금은 개발자들이 각자 인터넷에서 필요한 것을 내려받습니다. 같은 라이브러리를 스무 명이 스무 번 받고, 외부 사이트가 잠깐 멈추면 모두의 빌드가 함께 멈춥니다. Nexus는 그 사이에 서서 한 번만 받아 두고 모두에게 나눠 주는 역할을 합니다.

Nexus가 해 주는 일은 크게 세 가지입니다.

  • 받아서 보관하기 — 외부에서 내려받은 라이브러리를 사내에 캐싱해 둡니다.

  • 우리 것을 담아두기 — 우리가 만든 공통 모듈이나 빌드 결과물을 보관합니다.

  • 하나의 창구로 묶기 — 여러 저장소를 주소 하나로 합쳐서 보여 줍니다.

Repository 특징

Repository에는 대표적으로 3가지 종류가 있습니다.

  1. Proxy Repository - 외부 저장소를 대신 조회하고 결과를 캐싱할 수 있습니다.

  2. Hosted Repository – 우리가 만든 산출물을 직접 Repository에 업로드할 수 있습니다.

  3. Group Repository – 여러 저장소를 하나의 주소로 묶어서 이용할 때 사용됩니다.

관리자가 Proxy, Hosted Repository들을 Group Repository에 묶어 준다면 사용자는 Repository를 이용할 때는 Group Repository를 이용하여 하나의 Repository만 사용하면 됩니다.

Repository 구성 예시

저장소 이름

형식

타입

용도

maven-public

maven2

group

백엔드 개발자가 바라보는 주소 (아래 셋을 묶음)

maven-releases

maven2

hosted

우리가 만든 정식 릴리스 JAR

maven-snapshots

maven2

hosted

개발 중인 JAR

maven-mirror

maven2

hosted

외부에서 반입한 라이브러리

Nexus의 패키지 지원 포맷

Java(Maven·Gradle), 프론트엔드(npm), 파이썬, 도커 이미지, 리눅스 패키지까지 20종이 넘는 형식을 한 대의 서버에서 모두 다룰 수 있다는 점이 가장 큰 장점입니다. 언어별로 저장소를 따로 세울 필요가 없습니다. 아래는 지원하는 패키지의 종류이며 그 외 Terraform, Yum 등이 있습니다.

image1.pngimage2.png

image3.pngimage4.png

내부망에서의 활용

망분리 환경에서는 한 가지 큰 제약이 생깁니다. 내부망 서버는 인터넷으로 나갈 수 없습니다. 그래서 "밖에서 대신 사다 주는" Proxy 저장소를 쓸 수 없고, 대신 외부에서 미리 받아 둔 것을 안으로 들여오는 반입 절차가 필요합니다.

가장 널리 쓰이는 구성은 Nexus를 두 대 두는 방식입니다. 외부망(또는 DMZ)에 한 대를 두어 필요한 것을 미리 받아 두고, 내부망에 한 대를 두어 개발자에게 나눠 줍니다. 두 대 사이는 망연계 시스템으로 정기적으로 옮깁니다.

  [인터넷] → [외부망 Nexus · Proxy] ← 필요한 것을 미리 받아 캐싱
                    ↓ 추출 → 검증(해시·백신·취약점) → 승인
      ═══ 망분리 경계 · 망연계 시스템으로 전송 ═══
                    ↓
  [내부망 Nexus · Hosted] → [개발자 PC / CI 서버]

내부망 Nexus 도입의 장점

영역

도입 전

도입 후

라이브러리 추가

반입 신청 후 며칠 대기

이미 반입된 것은 바로 사용

의존성

빠진 것을 하나씩 재신청

빌드 한 번으로 일괄 확보

신규 세팅

환경 맞추는 데 며칠

빌드 명령 한 번이면 끝

반입 경로와 감사

USB·메일 등 제각각, 증명 어려움

창구 하나, 기록이 곧 증적

보안 관점

내부망에서 Nexus를 사용하더라도 외부의 Nexus 서버에는 노출이 되기 때문에, 각 계정 및 레포지토리의 Role과 Privilege 설정은 중요합니다.

Privilege를 통해서 사용자의 레포지토리 사용 권한을 나눌 수 있게 됩니다.

대략적으로 browse, read, add, edit, delete 기능이 대표적입니다. 따라서 개발자에게 단순 다운로드 권한만 필요하다면 read와 browse 정도만 부여하고, 업로드가 필요한 경우에만 add 권한을 추가하는 식으로 구성할 수 있습니다.

관리자 계정은 모든 권한을 가지고 있기 때문에 일반적인 Artifact 업로드나 다운로드 작업에 사용하는 것은 권장되지 않습니다.

Sonatype 역시 admin 계정은 초기 설정이나 관리 작업 등 전체 권한이 필요한 경우에 한정하여 사용하고, 평상시에는 권한이 제한된 별도의 계정을 사용할 것을 권장합니다.

실전 예시( Java + Gradle )

(1) 인증 정보 — gradle.properties

비밀번호를 소스에 넣지 않도록 홈 디렉터리의 설정 파일이나 환경 변수를 씁니다. CI에서는 개인 계정 대신 Nexus의 User Token을 발급해 쓰는 것을 권장합니다.

# ~/.gradle/gradle.properties
nexusUrl=https://nexus.example.local
nexusUser=build-bot
nexusToken=xxxxxxxx-xxxx-xxxx

(2) 라이브러리를 가져올 곳 — settings.gradle

Gradle은 플러그인과 라이브러리를 서로 다른 경로로 받아옵니다. 둘 다 지정해야 합니다. 폐쇄망에서 이걸 놓치면 "라이브러리는 받아지는데 플러그인에서 멈추는" 현상이 생깁니다.

pluginManagement {
    repositories {
        maven {
            url = uri("${nexusUrl}/repository/gradle-plugins/")
            credentials { username = nexusUser; password = nexusToken }
        }
    }
}

dependencyResolutionManagement {
    // 하위 모듈이 mavenCentral()을 임의로 선언하지 못하게 막습니다
    repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
    repositories {
        maven {
            url = uri("${nexusUrl}/repository/maven-public/")
            credentials { username = nexusUser; password = nexusToken }
        }
    }
}

(3) 빌드 결과물 올리기 — build.gradle

버전에 SNAPSHOT이 붙어 있으면 개발용 저장소로, 아니면 릴리스 저장소로 보냅니다. 릴리스 저장소는 Nexus 설정에서 덮어쓰기를 막아 두는 것이 좋습니다. 같은 버전인데 내용물이 다른 상황을 구조적으로 차단할 수 있습니다.

plugins { id 'java'; id 'maven-publish' }

publishing {
    publications { maven(MavenPublication) { from components.java } }
    repositories {
        maven {
            url = version.toString().endsWith('SNAPSHOT')
                ? "${nexusUrl}/repository/maven-snapshots/"
                : "${nexusUrl}/repository/maven-releases/"
            credentials { username = nexusUser; password = nexusToken }
        }
    }
}

자주 겪었던 문제

  1. 파일 빌드를 진행하면 파일은 올렸는데 Gradle이 못 찾음는 경우가 간혹 발생하는데, 메타데이터가 갱신되지 않았습니다. Nexus의 Repair - Rebuild Maven repository metadata 작업을 실행하거나 레포지토리에서 Invalidate cache를 눌러 캐시를 초기화해 줍니다.

  2. Nexus 서버의 용량을 관리해야 합니다. Proxy, Hosted 레포지토리는 지속적으로 반입한 데이터가 계속 쌓이게 됩니다. 관리자는 Cleanup Policy 설정을 통해서 오래된 스냅샷 데이터를 정리하도록 관리해야 합니다. Compact blob store를 정기적으로 실행합니다.

마무리

Nexus는 화려한 도구는 아닙니다. 하지만 한 번 세워 두면 개발자가 라이브러리를 기다리는 시간이 사라지고, 보안 담당자는 무엇이 들어왔는지 한곳에서 확인할 수 있게 됩니다. 보안과 개발 속도는 흔히 부딪힌다고들 하지만, 적어도 이 영역에서는 잘 만든 창구 하나가 둘 다 좋아집니다.

참고 자료

· Sonatype Nexus Repository 공식 문서 — Repository Types / Community Edition Onboarding (help.sonatype.com)

Bang

Site footer