반응형
이 글은 "private npm registry" 를 의미하는 사내 npm 저장소를 다룬다.
이를 위해 Verdaccio 를 이용하는데, 전반적인 이해와 사용 방법을 알아본다.
본인은 실제로 우리가 사용하는 npm 에 대해 조금 더 알게 된 계기가 되었다.
사내 npm 저장소를 구축할 일이 없어도 유용한 글이 될것이라 생각한다.
Verdaccio - https://github.com/verdaccio/verdaccio

 

private npm registry 는 무엇인가?

 

우리는 현재 npm 을 통해 많은 모듈들을 이용한다.

npm 에서 많은 모듈을 우리는 그저 편하게 install 하여 사용하고 있다.

우리가 이렇게 사용할 수 있는 건, npm 은 public 하게 제공해주기 때문이다.

반대로 private 이라면, 의미 그대로 외부적으로 노출되지 않는 npm registry 를 뜻한다.

 

private npm registry 은 왜 필요한가?

 

정확히는 private package 를 원하는 것이다.

회사 사내에서 많은 프로젝트를 진행하다보면, 재사용할 수 있는 모듈이 많을 것이다.

팀 내부 또는 다른 팀에서도 충분히 사용할 수 있을거라 판단된다면, 많은 곳에서 쓰이길 바랄 것이다.

우리는 이러한 모듈들을 npm 에 통해 패키지화해서 공유할 수 있다.

하지만 보안상 외부에 노출하기 어려운 것들도 있고, 너무 오픈되어 있어 관리 이슈가 좋지 못하다.

이를 위해, 오직 본인이 속한 조직을 위한 npm registry 를 구축하는 것을 private npm registry 라고 할 수 있다.

 

private npm registry 은 어떻게 구축하는가?

역시나 이미 누군가 잘 만들어주셨다.

verdaccio 라는 것을 활용하면 된다.

이전에는 sinopia 를 많이 사용했고, 현재는 이를 기반으로 발전해온 verdaccio 를 사용한다.

우리가 아는 create-react-app, storybook, angluar cli, babel 등 많은 곳에서 이를 활용하고 있다.

하지만 이들이 사용하는 목적은 완전히 private npm 을 위함은 아니다.

즉, verdaccio 또한 이를 위해서만 존재하는 것은 아니다.

유스케이스 중 private npm 을 포함하고 있을 뿐이다.

문서에서 명시된 이점은 다음과 같다.

 

  • Use private packages
  • Cache npmjs.org registry
  • Link multiple registries
  • Override public packages
  • E2E Testing

 

간략히 설명하겠고, 자세한 건 공식 문서를 참고하길 바란다.

 

Use private packages

위에서 언급한 내용이자 이 글의 주제이다.

 

Cache npmjs.org registry

만약 npmjs.org 서버가 느리거나, 죽게 되면 어떻게 될까?

이러한 이슈를 방지하기 위해 미리 필요한 패키지들을 캐시하여 대비할 수 있다.

 

Link multiple registries

하나의 프로젝트에서 여러 개의 registry 의 모듈을 가져올 수 있다.

verdaccio 에서 제공하는 기능인 uplinks 를 참고하면 된다.

 

Override public packages

본인의 프로젝트에 오픈 소스를 사용하고 있었는데, 버그를 발견하여 PR 를 날렸지만 승인되지 않거나 지연되고 있을 경우가 존재한다.

이러한 경우 본인이 구축한 npm 서버에 반영된 코드를 올려놓고 사용할 수 있다.

 

E2E Testing

여기서 E2E 테스트는 publish 하는 패키지들에 대해 체크를 의미한다. *publish - npm 서버에 업로드 하는 행위

local npm registry 를 통해 publish 를 시뮬레이션 할 수 있다.

위에서 언급한 create-react-app, storybook 등에서 사용하고 있는 방식이다.

CRA 에서 사용된 히스토리를 참고해보면 좋을 것이다.

https://github.com/facebook/create-react-app/compare/99c14e710ffb01d1c4a1124fc3ed2172bf58afbd...1098a4a177521f06febb1fcf7da94791febb19ba

 

여기서부터는 사용 방법에 대해 알아본다.

 

$ npm install -g verdaccio

 

로컬에서 global 로 설치한 후, verdaccio 명령어를 실행하면 된다.

로컬 서버가 실행되는 것을 볼 수 있다.

http://localhost:4873 으로 접속하면 아래와 같은 페이지가 보여진다.

 

 

그리고 다음과 같은 로그를 확인할 수 있다.

 

warn --- config file - /Users/mygumi/.config/verdaccio/config.yaml
warn --- Verdaccio started
warn --- Plugin successfully loaded: verdaccio-htpasswd
warn --- Plugin successfully loaded: verdaccio-audit
warn --- http address - http://localhost:4873/ - verdaccio/4.5.1

 

우선 주의깊게 봐야하는 건 2가지이다.

 

  • config.yaml
  • verdaccio-htpasswd

 

우선 config.yaml 은 verdaccio 의 전반적인 설정 파일이다.

우리가 원하는 기능의 대부분은 config.yaml 파일을 통해 제공되어진다.

파일을 확인해보면 디폴트값은 대략 다음과 같다.

 

storage: ./storage
auth:
  htpasswd:
    file: ./htpasswd
uplinks:
  npmjs:
    url: https://registry.npmjs.org/
packages:
  '@*/*':
    access: $all
    publish: $authenticated
    proxy: npmjs
  '**':
    access: $all
    publish: $authenticated
..........

 

더 길지만 여기서 언급하거나 다룰 것들만 설명한다.

 

storage

publish 되는 패키지들 존재하는 디렉토리가 된다.

즉, 모든 패키지들은 ./storage 경로에 저장되는 것이다.

직접 publish 하고 저 경로를 확인해보면, 새로 추가된 것을 확인할 수 있다.

만약 폴더를 삭제하면, local npm 에도 사라지게 된다.

 

auth

사용자 인증에 대한 데이터를 의미한다.

verdaccio 는 기본 인증을 htpasswd 기반으로 한다.

관련된 데이터 파일이 ./htpasswd 에 저장된다는 것을 의미한다.

실제로 사용자 등록을 하면 username 과 암호화된 패스워드가 파일에 추가된다.

아래에서 확인해볼 것이다.

 

uplinks

유스케이스에서도 언급했었다.

디폴트 값은 실제 npmjs.org 서버로써, 만약 npm install 하는 패키지가 local npm 에 없다면, npmjs.org 에서 내려받게 된다.

 

packages

각 패키지들에 대한 권한을 부여한다.

'@*/*' 는 verdaccio 에서 private 패키지에는 prefix 를 @ 로 권장한다. ex) @samsung/module, @tistory/module1

@ 로 시작되는 패키지는 접근은 누구나 가능하다는 것이고, publish 의 경우에는 인증된 사용자만이 가능하다는 의미이다.

*prefix 를 활용해야하는 이점과 인증된 사용자에 대해서는 아래에서 계속 설명할 것이다.

 

우선 하나의 패키지를 publish 해보자.

위에서 언급했듯이, 만약 패키지 권한이 $authenticated 라면 인증이 필요하다.

인증을 위해 사용자 등록을 해야한다.

npm adduser 명령어를 통해 할 수 있다.

 

$ npm adduser --registry http://localhost:4873

 

이건 실제 npm 서버를 사용하는 것과 동일하다.

다만, 사용자를 등록할 서버의 경로만 다시 설정해준 것이다.

Username, Password, Email 을 등록하면 "~ logged in ~" 로그를 확인할 수 있다.

위에서 언급한대로 htpasswd 파일을 열어보면 관련 데이터가 들어가있는 모습을 볼 수 있다.

혹시나 로그인된 상태를 확인해보고 싶으면 npm whoami 로 확인할 수 있다.

 

$ npm whoami --registry http://localhost:4873
$ npm login --registry http://localhost:4873 // 로그인
$ npm logout --registry http://localhost:4873 // 로그아웃

 

이제 publish 가 가능한 상태가 되었다.

publish 를 위해 빈 프로젝트에 index.js 와 package.json 을 생성한다.

 

// index.js
console.log("Hi");

// package.json
{
  "name": "@tistory/module1",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {},
  "devDependencies": {},
  "keywords": [],
  "author": "mygumi",
  "license": "ISC",
  "description": ""
}

 

그 후 npm publish 명령어를 통해 업로드한다.

 

 npm publish --registry http://localhost:4873

 

성공적으로 완료되었다면, 관련 패키지를 볼 수 있을 것이다.

이로써, 패키지는 원하는 곳에서 npm install 을 통해 내려받을 수 있다.

 

 npm install --registry http://localhost:4873 @tistory/module1

 

권한이 $all 이라면, 누구나 install 할 수 있을 것이고, $authenticated 라면, 로그인을 해야한다.

여기까지 기본적인 기능들을 사용할 수 있다.

 

하지만 한가지 문제가 존재한다.

우리가 원하는 건 말 그대로 Private 한 것이다.

하지만 사실 npm adduser 는 누구나 가능하다는 점이 private 하지않다.

결과적으로는 npm adduser 를 막아야한다.

이는 config.yaml 에서 제공해준다.

 

auth:
  htpasswd:
    file: ./htpasswd
    # Maximum amount of users allowed to register, defaults to "+inf".
    # You can set this to -1 to disable registration.
    max_users: -1

 

max_users 에 대해 주석처리를 풀고 값을 -1 로 지정해주면 된다.

그러면 서버는 npm adduser 는 요청을 거부하게 된다.

그리고 서버에 있는 htpasswd 파일에 직접 접근하는 방식으로 사용자 관리를 private 하게 할 수 있다.

자세한 건 다음 링크를 참고하면 된다. (https://hostingcanada.org/htpasswd-generator/)

 

마지막으로 private 패키지에는 prefix 를 권장하는 이유를 알아본다.

우리는 여지껏 npm 명령어에 --registry http://localhost:4873 를 같이 작성해야했다.

여러 개의 registry 를 사용한다면, npm 명령어에 --registry 옵션을 매번 경우에 따라, 다르게 지정해줘야한다.

이건 조금 번거러운 작업일 수도 있고, 사용자에게는 혼란을 줄 수 있다.

 

$ npm install react
$ npm install --registry http://localhost:4873 @tistory/module1

 

이것을 쉽게 해결할 수 있는 방법이 prefix 이다.

prefix 를 통해 registry 를 암묵적으로 정하는 것이다.

@tistory/* 의 이름을 가진 패키지는 private npm 서버를 바라보는 것이고, 이외에는 실제 npm 을 바라본다고 가정한다.

그러면 우리는 npm config 명령어를 통해 registry 를 명시해줄 수 있다.

 

$ npm config set @tistory:registry http://localhost:4873

 

명령어를 입력하면 .npmrc 파일에 저장된다.

또는 아래와 같이 .npmrc 파일에 직접 셋팅해줄 수도 있다.

 

.npmrc

@tistory:registry=http://localhost:4873

 

이제는 여지껏 npm 명령어에서 --registry 를 명시한 거를 생략해도 된다.

@tistory 로 시작하는 패키지는 local private 서버를 바라보고, 이외에는 npmjs.org 서버를 바라보게 된다.

 

// before
$ npm install react
$ npm install --registry http://localhost:4873 @tistory/module1

// after
$ npm install react
$ npm install @tistory/module1

 

prefix 은 단순히 가독성뿐만 아니라 이러한 방식으로 편의성을 높혀줄 수 있다.

이로써, 사용자는 혼란 없이 사용할 수 있게 된다.



출처: https://mygumi.tistory.com/371 

반응형

+ Recent posts