이 전에 준비한 자료들을 회의 때 발표했더니, 다른 개발자분들이 너무 좋아하셨습니다. 스타일 라이브러리도 전 글에서 언급했던 부분으로 강력하게 어필하였더니, 모두 좋다고 하셨습니다. ( 뭔가 총대를 멘 기분 … )
근데 한 가지 문제점이 있었습니다.
우리 회사는 폐쇄망 환경에서 개발하고 있었고, 모든 소스는 외부로 노출되서는 안된다
내가 테스트로 패키지를 배포했던 방식은, 오픈소스화 해서 올린 것이였습니다. 그러나 사내에서 진행하는 디자인 시스템 프로젝트는 모든 것이 은밀한 폐쇄망에서 이루어져야 합니다.
npm private registry
를 이용해보는 것은 어떠할까? 하고 제안해보았지만 별도의 비용이 발생하기 때문에 반려되었습니다.
이 때 팀장님이 하나 제안해주셨습니다.
nexus 에 registry를 구축해보는건 어떨까요?
처음 들어봤습니다… 넥서스?,, 그게뭔데,,? 내가 아는 넥서스는 롤 넥서스밖에 없는데 말인데요…
Sonatype Nexus
Nexus는 소프트웨어 아티팩트(라이브러리, 컴포넌트, 컨테이너 이미지 등)를 저장하고 관리하는 바이너리 저장소 관리자 라고 합니다.
- Maven
- npm
- Docker
- PyPI
- NuGet
- RubyGems
- Helm …
위에 언급된 저장소와 관련된 패키지를 업로드하여 은밀하게 내려받고 사용할 수 있다고 합니다..
이번 글에서는, nexus를 도커 컨테이너를 이용하여 구축하고, nexus npm registry에 디자인 코어를 구축해보는 과정을 정리해보려고 합니다.
docker-compose.yaml 작성
먼저 nexus를 띄우기 위해 사내에서 사용하고 있던 docker를 사용하여 이미지를 pull 받고 컨테이너를 4081포트에 띄워주었고, /home/test/nexus-data
의 파일을 마운트 시켜주어 띄워주었습니다.
version: '2'
services:
nexus3:
image: sonatype/nexus3:latest
container_name: 'nexus3'
restart: always
ports:
- '4081:4081'
- '4082:4082'
volumes:
- '/home/test/nexus-data:/nexus-data'
environment:
- INSTALL4J_ADD_VM_PARAMS=-Xms1g -Xmx1g -XX:MaxDirectMemorySize=2g
networks:
default:
external:
name: devops
컨테이너 구동
저희는 docker 20 버전대를 쓰고 있었기 때문에 커맨드가 22버전대와 조금 달랐습니다.
$ docker-compose up -d
docker-compose.yaml
이 위치한 경로에서 위의 커맨드를 입력해 nexus 컨테이너를 구동시켜주었습니다.
nexus 구동 및 초기 설정
http://{ip}
:4081
로 접속하게 되면 다음과 같은 화면이 나오게 되고, 로그인을 먼저 해야합니다.
컨테이너 설정 당시 관리자 정보를 설정했었습니다.
기억이 나지 않는다면, 볼륨을 마운트해주었던 경로에 admin.password
라는 파일이 존재합니다.
$ cat ./admin.password
유저 생성하기

로그인을 한 후에, 유저 정보를 먼저 세팅해주어야합니다.
admin 을 제외한 제 이름 초성으로 하나 만들어주겠습니다.
상단 nav 바에서 톱니바퀴 버튼을 클릭한 후, 좌측 sideBar에서 Security → Users를 클릭합니다.
그 다음 Create User 버튼을 클릭하여 아래 페이지에 접속합니다.

만들면 다음과 같이 등록된 유저정보를 확인할 수 있습니다.

Repository 생성하기
유저를 생성한 후, Repository를 생성해주어야합니다.
상단 nav 바에서 톱니바퀴 버튼을 클릭한 후, 좌측 sideBar에서 Repository → Repositories 를 클릭합니다.

그리고 Create Repository 버튼을 눌러 form에 진입합니다.

Blob Store는 default로 설정 후, 생성해주었습니다.
그리고, 패키지 명을 @
를 접두사로 붙혀준 이유는, 추후에 패키지 스코프를 지정하기 위해서입니다.

Repository
는 npm registry와 같은 역할을 합니다. 추후에 라이브러리를 패키징하여 버전 패치를 진행할 수도 있고, 사용하는 측에서 설치할 때, 패키지 파일을 가져오는 저장소가 됩니다.
위 사진에 나와있는 URL http://183.111.104.98:4081/repository/inzent-ui-core/
이 추후 패키지 업로드, 설치에 사용될 URL 이 됩니다
패키지 nexus에 업로드 해보기
프로젝트 세팅과정은 npm registry 구축해보기 에서 한 번 언급했기 때문에 생략하겠습니다.
프로젝트 최상위 경로에서 nexus repository url로 npm 로그인을 진행해주겠습니다.
아래 사진과 같이 registry prefix를 커맨드에 추가하여 로그인해줍니다.

$ npm login --registry http://183.111.104.98:4081/repository/inzent-ui-core/
> id: admin
> password
> Logged in on http://183.111.104.98:4081/repository/inzent-ui-core/.
$ npm whoami --registry http://183.111.104.98:4081/repository/inzent-ui-core/
> admin
그리고 package.json의 내용은 다음과 같이 수정해주었습니다.
{
"name": "@inzent/ui",
"publishConfig": {
"registry": "http://183.111.104.98:4081/repository/inzent-ui-core/"
},
"type": "module",
"version": "1.0.12",
"files": [
"dist",
"ui.css"
],
//..
}
publishConfig 필드의 registry를 nexus registry url로 변경해주었습니다.
npm publish
빌드 후, npm publish를 진행해보겠습니다.

위 사진과 같이 성공적으로 publish가 이루어진 걸 확인할 수 있습니다.
nexus repository의 정보도 한 번 확인해보겠습니다.
상단 nav 바에서 상자 버튼을 클릭한 후, 좌측 sideBar에서 Browse를 클릭한 후, 등록했던 repository 명으로 들어갑니다.
그리고, inzent-ui-core 를 클릭하여 들어가보겠습니다.

업로드한 버전은 @inzent/[email protected] 버전입니다.
좌측 Summary를 확인해보면 uploader와 Blob updated 란을 통해 업로드한 유저와 업데이트 한 유저를 확인할 수 있습니다.
패키지 설치해보기
현재 테스트 프로젝트의 package.json 의 의존성은 다음과 같습니다.
"dependencies": {
"@inzent/ui": "^1.0.12",
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-switch": "^1.1.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.468.0",
"path": "^0.12.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"tailwind-merge": "^2.5.5",
"tailwindcss-animate": "^1.0.7",
"vaul": "^1.1.2"
},
또한, .npmrc
파일을 생성해주어 registry url을 지정해주었습니다.
registry=http://183.111.104.98:4081/repository/inzent-ui-core/
테스트 프로젝트에서 패키지를 설치해보겠습니다. 그러나,
설치 시, 다음과 같은 오류가 발생하였습니다.
npm error code E404
npm error 404 Not Found - GET http://183.111.104.98:4081/repository/inzent-ui-core/yocto-queue/-/yocto-queue-0.1.0.tgz - Package 'yocto-queue' not found
npm error 404
npm error 404 'yocto-queue@http://183.111.104.98:4081/repository/inzent-ui-core/yocto-queue/-/yocto-queue-0.1.0.tgz' is not in this registry.
npm error 404
npm error 404 Note that you can also install from a
npm error 404 tarball, folder, http url, or git url.
npm error A complete log of this run can be found in: C:\Users\USER\AppData\Local\npm-cache\_logs\2025-03-17T00_43_53_182Z-debug-0.log
이유는 다른 패키지가 지정된 registry url 저장소에 존재하지 않기 때문입니다.
패키지 스코프
패키지 스코프는 npm에서 패키지를 관리할 때, 특정 범위를 설정하여 패키지의 이름을 구분하고, 패키지 그룹화를 가능하게 하는 기능입니다. 이를 통해 여러 팀이나 프로젝트가 서로 충돌 없이 패키지를 관리할 수 있도록 도와줍니다.
패키지 이름 앞에 @
기호를 사용하여 나타냅니다.
배포한 패키지 명은 @inzent/ui 입니다. 패키지 스코프는 @inzent가 됩니다.
따라서 .npmrc
의 파일을 다시 수정해주었습니다.
@inzent:registry=http://183.111.104.98:4081/repository/inzent-ui-core/
수정 후, 다시 설치해보겠습니다.

성공적으로 설치가 완료된 모습입니다.

또한, 성공적으로 module을 import 해오며 타입추론과 JSDOC도 잘 보이는 것 같습니다.
storybook도 같이 배포해보자
docker-compose.yaml
추가적으로 공통컴포넌트를 만드는 디자인 코어 프로젝트기 때문에 storybook도 같이 구성하면 좋을 것 같아 storybook도 같이 배포해보겠습니다.
기존 docker-compoase.yaml 파일에 nginx 이미지만 추가해주고, 4083 포트로 정적파일을 서빙해주는 스크립트를 추가로 작성했습니다.
version: '2'
services:
nexus3:
image: sonatype/nexus3:latest
container_name: 'nexus3'
restart: always
ports:
- '4081:4081'
- '4082:4082'
volumes:
- '/home/test/nexus-data:/nexus-data'
environment:
- INSTALL4J_ADD_VM_PARAMS=-Xms1g -Xmx1g -XX:MaxDirectMemorySize=2g
storybook:
image: nginx:latest
container_name: 'storybook'
restart: always
ports:
- '4083:80'
volumes:
- '/home/test/storybook/storybook-static:/usr/share/nginx/html'
networks:
default:
external:
name: devops
로컬에서 storybook 빌드 파일을 압축하여 서버로 전송하는 shell script를 작성해주었습니다.
#/bin/bash
rm ./storybook-build.tgz
echo -e "\033[1;36m[-] BUILD STORY BOOK ... \033[0m"
npm run build-storybook
echo -e "\033[1;32;40m[+] BUILD SUCCESS! \033[0m"
tar -czf storybook-build.tgz ./storybook-static
echo -e "\033[1;36m[-] SUCCESS TAR AND CONNECT TO 183.111.104.98:/home/test\033[0m"
scp -P 2022 ./storybook-build.tgz [email protected]:/home/test/storybook
그리고 ssh 서버에 접속하여 압축을 풀고 브라우저에서 확인해보겠습니다.

성공적으로 배포된 것을 확인할 수 있었습니다.
이번 테스트 구축을 통해 어떤 방향으로 디자인 시스템을 구축해나가야 할 지 열심히 의견제시를 할 수 있을 것 같습니다. 더 좋은 방법이 있다면 더 포스팅해보려 합니다.
프로젝트에 제대로 들어가게 되면 과정을 더 소개할 예정입니다.