Nexus를 이용한 라이브러리 구축하기
Nexus를 이용하여 여러 서비스에서 사용하는 공통 라이브러리를 한곳에서 관리하기
Maven Repository 및 Docker Registry로 사용해보자
Spring, Maven 기반의 여러가지 프로젝트를 개발하다보니 항상 공통적으로 적용되는 항목들이 있었다. 로그인, 유틸성 클래스, Spring 설정 클래스, Enum.. 등등 여러가지로 중복되는 코드가 많이 있는데 조금만 수정되더라도 여러 프로젝트에 수정해주는 것도 번거롭기도 하고 때론 같은 기능인데 프로젝트마다 싱크가 맞지 않아 서로 다른 기능을 하게 되기도 하는 문제가 있다.
그림1. 서비스 별로 각각 중복 코드를 복사해서 넣어야 했다.
Nexus를 사용하면 이러한 공통 코드를 모아서 한 곳에서 관리할 수 있는 장점이 있다. 또한 이러한 용도 외에도 공통으로 사용하는 의존성들도 같이 관리하면 의존성조차 프로젝트별로 따로 추가해주지 않아도 되는 장점도 있다. 또, 개발환경이 폐쇄적일 경우에도 오픈된 Nexus를 통해 외부 의존성을 주입받을 때 사용하기도 한다.
우선 공통 라이브러리로 사용하겠다는 목적으로 구축을 해보겠다.
Nexus 설치(다운로드) 및 Repository 생성하기
1. Nexus 다운로드
다운로드 페이지를 통해 원하는 환경에 해당하는 파일을 다운받는다. 나는 테스트 상 Docker 기반으로 구성했었는데, 리눅스 기반으로 메모하려고 한다. 해당 링크에서 Unix archive
링크를 wget을 통해 다운받는다.
wget https://download.sonatype.com/nexus/3/nexus-3.43.0-01-unix.tar.gz # 다운로드
tar -zxvf nexus-3.43.0-01-unix.tar.gz # 압축해제
Nexus는 Jdk 1.8 이상이 필요한데 설치되어 있지 않으면 별도로 설치한다. (과정생략)
2. 유저 생성 및 권한 설정
Nexus 전용으로 사용할 유저를 생성한다. (root로 진행 시 생략해도 됨)
sudo useradd nexus
visudo
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
nexus ALL=(ALL) NOPASSWD:ALL
sudo chown -R nexus:nexus {nexus경로}/nexus
sudo chown -R nexus:nexus {nexus경로}/sonatype-work
nexus경로/nexus/bin/nexus.rc 파일을 수정한다.
run_as_user="nexus" # root로 진행 시 root로 적으면 된다.
3. 부팅 시 서비스 등록
/etc/init.d
sudo ln -s {nexus경로}/nexus/bin/nexus /etc/init.d/nexus
4. Nexus 서비스 실행
/etc/init.d/nexus start
포트 변경은 {nexus경로}/nexus/etc/nexus-default.properties의 application-port 에서 수정한다 (기본8081)
도커로 설치하면 더 간단하다. 그냥 nexus-data:/nexus-data 볼륨 및 8081 포트 바인딩만 해주고 실행하면 된다. 권한 문제 발생시엔
chown -R 200:200 nexus-data
해주면 된다.
5. 관리 페이지 접속
서비스가 로드 될 때까지 기다린 후 HOST:8081로 접속하면 Nexus Repository Manager화면을 볼 수 있다.
우측 상단의 sign in 버튼으로 로그인한다. admin 계정의 초기 비밀번호는 sign in 버튼 누를 시 나오는 경로에서 볼 수 있다.
Docker Image의 경우
/nexus-data/admin.password
이고 linux로 설치한 경우{nexus경로}/sonatype-work/nexus3/admin.password
에서 확인할 수 있다.
6. Repository 생성하기
관리자로 로그인 하고 공통 라이브러리로 사용할 Repository를 생성한다. Spring + Maven 기반으로 구성할 것이기 때문에 maven2(hosted)를 선택한다.
Repository가 생성되면 Browse 탭에서 생성 된 Repository를 볼 수 는데 처음 배포 이후에는 버전별, 스냅샷 별로 코드에 적용할 수 있도록 구분되있는 것을 볼 수 있다.
여기까지 하면 Nexus를 사용하기 위한 설정은 끝난다.
공통 라이브러리 설정
1. Library 생성 및 설정
Spring boot, Maven 기반으로 빈 프로젝트를 생성한다. (과정 생략)
공통으로 사용할 의존성을 주입하거나 별도의 기능들을 개발한 후 pom.xml
에 다음 정보를 입력한다.
pom.xml
...
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
...
<distributionManagement>
<snapshotRepository>
<id>nexus</id>
<name>common-library</name>
<url>http://HOST:8081/repository/common-library/</url>
</snapshotRepository>
<repository>
<id>nexus</id>
<name>common-library</name>
<url>http://HOST:8081/repository/common-library/</url>
</repository>
</distributionManagement>
여기에서 name은 위에서 생성한 repository의 name이고 id는 특정 nexus 서버임을 식별하는 아무 값이나 넣으면 된다. (ex. my-nexus)
2. 인증정보 설정하기
Nexus에 deploy 하기위해 배포 비밀번호를 설정해주어야 한다. 각각 Maven이 이 설치된 환경의 .m2
폴더에 settings.xml
을 생성한다.
settings.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>nexus</id>
<username>admin</username>
<password>설정한비밀번호</password>
</server>
</servers>
</settings>
id는 위에서 정한 Nexus 식별값, usename/password는 Nexus 인증정보로 설정한다. 관리계정을 노출시키지 않으려면 배포용 계정을 별도로 생성해서 사용하는 방법도 있다.
TIP linux vi로 복사 후 틀어진 포매팅은 gg=G를 입력하면 자동 정렬된다.
3. Nexus에 배포하기
mvn clean deploy
정상적으로 경로만 입력했다면 문제없이 배포되는 것을 볼 수 있다. 배포 이후 웹 매니저의 Browse에서 배포된 항목이 노출되는 것을 확인한다.
공통 라이브러리 가져다 쓰기
Nexus Repository에 배포된 common-library를 여러 프로젝트에서 가져다 쓰는 과정이다. 기존의 Spring boot project에서 pom.xml
설정만 수정해주면 된다.
pom.xml
...
<!-- in dependencies -->
<dependency>
<groupId>com.test.common.lib</groupId>
<artifactId>common-library</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
...
<repositories>
<repository>
<id>nexus</id>
<name>common-library</name>
<url>http://HOST:8081/repository/common-library/</url>
</repository>
</repositories>
Maven 의존성을 갱신하면 외부 라이브러리들과 동일하게 common-library 패키지의 기능들을 사용할 수 있게 된다.
Spring boot 공통 라이브러리가 패키지를 인식하지 못할 때
공통 라이브러리로 사용할 프로젝트를 Spring boot로 생성 시 사용하는 서비스에서 정상적으로 패키지를 받아오더라도 클래스를 불러다가 사용할 수 없는 경우가 있다. Spring boot 실행파일로서 jar 패키징 되어서 생기는 문제로, 일반적인 jar 파일로 빌드될 수 있도록 pom.xml을 수정해야한다.
pom.xml
<!-- <parent>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-parent</artifactId>-->
<!-- <version>2.7.7-SNAPSHOT</version>-->
<!-- <relativePath/> <!– lookup parent from repository –>-->
<!-- </parent>-->
pom.xml의 parent 영역을 삭제하고, 각각 Spring boot와 연동되어 자동으로 관리해주던 버전 의존성은 수동으로 달아주어야 한다. 이후 다시 deploy 하면 정상적으로 받아와 쓸 수 있는 것을 볼 수 있다.
deploy시 Maven 컴파일러 관련 버전 오류가 떴다면, properties에 해당 오류에 맞는 버전을 지정해주면 된다.
pom.xml
<properties>
<java.version>11</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding> <!-- 인코딩 깨질 때 -->
<project.reporting.outputEncoding>utf-8</project.reporting.outputEncoding> <!-- 인코딩 깨질 때 -->
</properties>
Nexus 3 버전 부터는 Docker Image 저장소로도 사용할 수 있다.
Docker Registry로 사용하기
1. Setting > Repository > Repositories > Create repository
docker(hosted)을 선택한다.
기본적으로 다음 세개 항목만 설정해준다
Name : docker registry 이름
HTTP : docker registry 사용 포트 (Nexus와 다른 포트 사용)
Enable Docker v1 api : v2는 https 강제화되므로 v1 사용 (https 쓸거면 v2로)
2. Registry가 생성되면 바로 저장소로 사용할 수 있다
# 원격 Registry 로그인
docker login -u <nexusId> -p <nexusPwd> <Nexus Repository Host>:<위에서Nexus Repository Docker Registry Port>
# 원격 배포를 위한 기존 이미지 태깅
docker tag <Image Name> <Nexus Repository Host>:<Nexus Repository Docker Registry Port>/<Remote Image Name>:<Remote Image Tag>
# 원격 리포지토리에 푸시
docker push <Nexus Repository Host>:<Nexus Repository Docker Registry Port>/<Remote Image Name>:<Remote Image Tag>
# 원격 리포지토리로부터 풀
docker pull <Nexus Repository Host>:<Nexus Repository Docker Registry Port>/<Remote Image Name>:<Remote Image Tag>
넥서스 포트와 도커 레지스트리 포트를 같게 했었는데 푸시가 안되서
(/v2 404 에러)
, 다르게 설정하니 정상적으로 구동되었다.
3. https를 사용하지 않는 경우
Https를 사용하지 않는 경우 docker login 단계부터 오류가 발생하는데, https -> http 통신이라 발생하는 오류다
이 때는 접속하는 쪽에서 insecure-registries
설정으로 에 사설 docker registry 서버의 IP를 추가해야 한다.
{
...
"insecure-registries": [
"192.192.192.192:12000" # 원격 registry 주소
]
}
docker-desktop 에서는
ettings -> Docker Engine
, 일반 docker에서는 daemon.json 수정
참 쉽다