Tooling

Node.js 인기 레포 6개의 미문서 환경변수 — 스캔 결과 공개

Express, NestJS, Supabase 등 6개 Node.js 프로젝트를 스캔해 실제 env 사용량과 문서화 수준의 격차를 분석한다.

6 min read
Node.js환경변수보안DevOps오픈소스
Node.js 인기 레포 6개의 미문서 환경변수 — 스캔 결과 공개

.env.example을 믿는가? 실제로는 훨씬 더 많은 환경변수가 코드 곳곳에 숨어 있다.

한 개발자가 GitHub API를 활용해 인기 Node.js 프로젝트 6개의 process.env 참조 수와 실제 문서화된 환경변수 수를 비교했다. 결과는 예상보다 훨씬 심각했다.

스캔 대상

프로젝트GitHub Stars유형
Express~65kHTTP 프레임워크
Fastify~32kHTTP 프레임워크
NestJS~68k애플리케이션 프레임워크
Strapi~63k헤드리스 CMS
Keystone~9k풀스택 CMS
Supabase~73kBaaS 플랫폼

결과: 프레임워크 vs 플랫폼

프레임워크와 플랫폼 사이에 명확한 차이가 있다.

Express, Fastify, NestJS는 라이브러리이기 때문에 의도적으로 환경변수를 거의 안 쓴다. 설정은 사용자 애플리케이션이 담당하도록 위임하는 구조다. .env.example 파일도 없는 게 정상이다.

플랫폼 툴은 다르다.

Strapi: process.env 참조 135개. 하지만 .env.example 파일 10개에 문서화된 변수는 "15개 정도". 120개 이상의 환경변수가 코드를 읽지 않으면 존재 자체를 알 수 없다.

Keystone: 112개 참조, .env.example 3개. 핵심 설정이 산문 형태로만 문서화되어 있어서 어떤 환경변수가 필요한지 파악하려면 직접 소스를 뒤져야 한다.

Supabase: 294개 참조, .env.example 24개. 그나마 가장 낫다. 인라인 주석과 보안 경고가 포함된 예시 파일이 있다. 하지만 270개 이상은 여전히 미문서 상태.

[💡 잠깐! 이 용어는?] 헤드리스 CMS: 콘텐츠 관리는 하지만 프론트엔드(화면)는 제공하지 않는 CMS. API로 콘텐츠를 제공하고, 렌더링은 별도 앱이 담당한다.

왜 이게 문제인가

1. 신규 기여자의 진입 장벽

오픈소스 프로젝트에 기여하려면 환경을 세팅해야 한다. .env.example이 불완전하면, 새 기여자는 "왜 빌드가 안 되지?"를 디버깅하는 데 시간을 쏟는다. 소스 코드를 전부 읽어야 필요한 환경변수를 파악할 수 있다.

2. 테스트/CI 환경의 비밀 크리덴셜

테스트용 크리덴셜은 거의 문서화되지 않는다. CI에서 필요한 환경변수를 알아내려면 CI 설정 파일을 역으로 분석해야 하는 경우가 많다.

3. 업데이트 동기화 부재

새 기능이 추가될 때 환경변수도 새로 생긴다. 그런데 .env.example 업데이트를 강제하는 메커니즘은 없다. 리뷰어가 놓치면 그냥 넘어간다.

핵심 문제는 최초 .env.example이 아니다. 코드베이스가 성장하면서 동기화를 유지하는 것이다.

envscan이 해결하려는 것

이 스캔을 수행한 개발자는 envscan이라는 도구를 개발 중이다. 소스 코드를 분석해서 모든 process.env 참조를 찾고, 실제 .env.example과 비교해 누락된 항목을 알려준다.

이미 envscan이 tera-log 콘텐츠에 올라와 있는데(관련 포스트 참고), 이번 스캔 결과는 그 도구가 왜 필요한지를 데이터로 보여준다.

이게 개발자에게 의미하는 것

직접 이 프로젝트들을 사용 중이라면:

  • 공식 문서만 믿지 말 것. 실제로는 더 많은 환경변수가 있을 수 있다.
  • 새 버전으로 업그레이드할 때 환경변수 변경 이력을 확인하라. 변경 로그에 없을 수도 있다.
  • 오픈소스에 기여한다면, 새 기능에 환경변수를 추가할 때 .env.example 업데이트를 PR에 포함시켜라.

자체 프로젝트를 관리한다면:

  • .env.example 업데이트를 PR 체크리스트에 넣어라.
  • CI에서 환경변수 누락을 감지하는 린트 단계를 추가하는 것도 방법이다.

마무리

문서화되지 않은 환경변수는 보안 문제가 아니라 DX 문제다. 새 팀원이 합류하거나 로컬에서 처음 실행할 때 막히는 경험은, 사실 .env.example 한 파일을 제대로 관리했다면 없었을 일이다. 작은 습관이 큰 차이를 만든다.


참고: