환경 변수

"An environment variable is a dynamic-valued object that can affect the way running processes will behave on a computer."

— POSIX.1 및 유닉스 시스템 매뉴얼

코드의 로직(영혼)과 설정값(육체)을 완전히 분리해 주는 마법이자, 초보 개발자들이 깃허브에 API 키와 패스워드를 올렸다가 해커들의 비트코인 채굴용 서버비를 선물하게 만드는 뼈아픈 교육용 도구. .gitignore에 .env 추가하는 걸 까먹고 커밋 푸시를 때려 사방에서 쏟아지는 슬랙 알림과 함께 등 뒤로 식은땀이 흘러내리는 스릴을 안겨주는 일등 공신

1. 개요

환경 변수(Environment Variable)는 운영체제(OS) 환경에서 동작하는 프로세스들이 전역적으로 참조할 수 있도록 동적으로 저장된 키-값(Key-Value) 형태의 변수다. 프로그램 코드 내부가 아닌, 프로그램이 실행되는 '외부 환경'에 동적으로 주입해 설정하는 값들을 의미한다. 대표적으로 실행 모드(development vs production), 데이터베이스 접속 주소, 외부 API 토큰 등이 이 환경 변수를 통해 주입된다. 이를 통해 코드 로직을 전혀 건드리지 않고, 단지 환경 변수값만 변경함으로써 프로그램의 동작 양상을 자유자재로 제어할 수 있게 된다.(...)

2. 12-Factor App과 설정값의 코드 격리 원칙

2.1. 소스코드에 비밀번호를 적지 말라!

클라우드 네이티브 애플리케이션 개발 방법론인 'The Twelve-Factor App'의 제3원칙은 바로 "설정(Config)을 코드와 완전히 격리하여 환경 변수에 저장하라"이다.

개발자들의 가장 흔하고 끔찍한 실수 중 하나는, 데이터베이스 비밀번호나 외부 서비스의 API Key를 소스코드 내부 변수에 버젓이 하드코딩해 두는 것이다. 이 상태로 코드를 Git에 커밋하고 GitHub 같은 공개 리포지토리에 푸시하는 순간, 전 세계 해커들이 돌리는 자동 스캐너에 0.1초 만에 포착된다. 그 결과, AWS 요금이 수천만 원 청구되거나 데이터베이스가 랜섬웨어로 잠기는 참극을 겪게 된다.

환경 변수를 도입하면, 소스코드에는 오직 process.env.DB_PASSWORDos.environ.get('API_KEY') 같은 참조 코드만 남겨둔다. 실제 실제 값은 로컬 개발 환경에서는 가상의 로컬 파일인 .env에 보관하고, 상용 배포 환경에서는 클라우드 플랫폼의 대시보드(Secret Management)에 따로 입력해 둠으로써 소스코드 유출 시에도 핵심 보안 기밀은 안전하게 수호할 수 있게 된다.(...)

3. 실무의 동반자: .env 파일과 OS 전역 변수의 차이

3.1. 환경 변수의 전파와 로컬의 구원자 dotenv

컴퓨터에서 환경 변수를 설정하는 고전적인 방법은 터미널에서 export DB_URL="mongodb://..." (리눅스/macOS) 혹은 setx DB_URL "..." (윈도우) 명령어를 직접 치는 것이다. 그러나 매번 컴퓨터를 켤 때마다, 혹은 개발 프로젝트를 바꿀 때마다 이 짓을 수동으로 하는 것은 미치고 팔짝 뛸 노릇이다.

이 귀찮음을 영리하게 해결해 주는 라이브러리가 바로 dotenv이다. 프로젝트 루트에 파일명 자체가 .env인 일반 텍스트 파일을 만들고, 그 안에 변수들을 적어두면, 프로그램 실행 시 dotenv 라이브러리가 이 파일을 읽어들여 마치 OS 환경 변수가 입력된 것처럼 메모리에 동적으로 주입해 준다.1 단, 이 .env 파일은 오직 나만의 로컬 비밀 주머니이므로, 절대 깃 저장소에 업로드되어서는 안 된다. 대신에 값들은 전부 비우고 변수 이름만 적어둔 가이드용 파일인 .env.example을 커밋하여 동료 개발자들에게 공유하는 것이 업계 표준 예절(Best Practice)로 작동하고 있다.2

4. 관련 밈 및 드립

4.1. 깃허브의 비트코인 채굴기 기증 천사

AWS나 구글 클라우드의 API 키가 적힌 코드를 .gitignore 누락 실수로 인해 퍼블릭 깃허브에 푸시했을 때 발생하는 참상을 가리키는 밈.

해커들이 상주하는 크롤러 봇들은 깃허브에 새로운 커밋이 올라오는 족족 'AWS_SECRET_ACCESS_KEY' 같은 키워드를 정규식으로 스캔한다. 키가 검출되면 수분 내에 수십 대의 최고 사양 GPU 인스턴스를 올려 비트코인 채굴에 사용한다. 다음 달 사용자는 수천만 원의 '서버 요금 핵폭탄' 고지서를 받아 들고 억장이 무너지게 되는데, 개발자 커뮤니티에서는 이들을 불쌍히 여기면서도 '자선 단체에 기증 잘했다'며 뼈 때리는 조롱 밈으로 사용한다.(...)

5. 여담

  • PATH 변수의 중요성: 환경 변수 중 최고 존엄이자 가장 널리 알려진 변수는 단연 PATH다. 어떤 디렉터리에서든 명령어(예: node, git)를 입력했을 때, OS가 이 실행 파일들을 어디서 찾아야 할지 헤매지 않도록 실행 경로 목록을 미리 지정해 두는 맵이다. 환경 변수 꼬임 에러의 90%는 이 PATH 경로 이중 등록이나 경로명 공백 오타에서 발생한다.
  • 대소문자 구분 이슈: 리눅스나 macOS(POSIX 표준 계열)는 환경 변수 이름의 대소문자를 완벽히 구별하지만, 윈도우는 구별하지 않고 혼용해서 쓴다. 예컨대 윈도우에서는 PathPATH가 같은 변수로 취급되어, 멀티플랫폼 코드를 짤 때 개발자들을 당황하게 만드는 미묘한 차이점 중 하나다.
  • 환경 변수 크기 제한: 무제한으로 쓸 수 있을 것 같지만, OS마다 환경 변수 총량 크기에 한계가 있다. 윈도우의 경우 단일 환경 변수의 최대 크기는 32,767글자이며, 리눅스 역시 버퍼 크기 제약이 존재해 너무 많은 벌크 데이터를 환경 변수에 밀어 넣으려다가는 실행 자체가 안 되는 먹통 에러를 만날 수 있다.(...)

6. 관련 문서

각주

  1. Node.js 환경에서는 npm i dotenv로 패키지를 설치해 사용해 왔으나, 최근 최신 Node.js v20+ 버전부터는 별도 패키지 설치 없이 --env-file=.env 플래그를 통해 자체적으로 로컬 .env 파일을 주입해 주는 기능을 마침내 공식 탑재했다.

  2. 실제로 소스코드 저장소를 클론받은 뒤 첫 번째로 하는 행동이 바로 .env.example 파일을 복사해서 .env로 이름을 바꾸고, 실제 비밀키를 채워 넣는 작업이다.