ORM - 환경변수 관리

Kjjedd·2026년 1월 26일

ORM

목록 보기
3/8
post-thumbnail

🌍 환경변수(Environment)란 무엇인가

Environment는 단순히 “환경”이라는 뜻이 아니다.
프로그램이 실행될 때 주변에서 영향을 주는 모든 조건을 의미한다.

  • 데이터베이스 주소
  • DB 계정 / 비밀번호
  • API Key
  • 실행 포트
  • 개발 / 테스트 / 운영 구분 값

즉, 코드는 같아도 환경이 바뀌면 동작이 달라질 수 있는 값들이다.


❌ .env 없이 환경변수를 관리하면 벌어지는 일

설정을 코드에 직접 적는 순간

처음 개발할 때 많은 사람들이 이렇게 시작한다.

DB_HOST = "192.168.1.100" 
DB_USER = "admin" 
DB_PASSWORD = "supersecret123" 
DB_NAME = "my_service" 

실행은 잘 되지만...

문제 ① 보안 사고는 예고 없이 터진다 🔥

이 코드가 GitHub에 올라가는 순간?

  • DB 비밀번호 전 세계 공개
  • API Key 탈취
  • 클라우드 요금 폭탄


문제 ② 환경이 바뀔 때마다 코드 수정

환경 DB 주소 목적
개발 localhost 로컬 테스트
테스트 test.company.com QA 검증
운영 prod.company.com 실서비스

.env가 없으면?

 
# 개발 
DB_HOST = "localhost" 

# 테스트 
DB_HOST = "test.company.com" 

# 운영 
DB_HOST = "prod.company.com" 

👉 환경 바뀔 때마다 코드를 수정한다.
👉 코드를 수정한다는 건 새 버그를 만들 기회를 추가하는 것이다.


문제 ③ 팀 협업 지옥 🤯

김철수:
    DB_HOST = "chulsoo-pc"
        ↓
       커밋

jay:
    코드 받음 → 접속 실패 😡
    DB_HOST = "jay-pc"
        ↓
       커밋

김철수:
    코드 받음 → 접속 실패 😡

이 상황의 본질은 이것이다.

“개인 환경 설정이 코드에 섞여 있다”

결과는?

  • 설정 덮어쓰기 반복
  • 의미 없는 커밋 증가
  • 팀원 간 스트레스 증가

문제 ④ Git 히스토리가 더러워진다

commit 1: 로그인 기능 구현
commit 2: DB 주소 변경 (개발)
commit 3: 버그 수정
commit 4: DB 주소 변경 (테스트)
commit 5: 새 기능 추가
commit 6: DB 주소 변경 (운영)

나중에 이 히스토리를 보면?

  • 기능 변경인지
  • 설정 변경인지
  • 왜 바뀐 건지

아무도 알 수 없다.


문제 ⑤ 운영 장애로 직행 🚨

# 개발용 설정 그대로 운영 서버에 배포
DB_HOST = "localhost"

운영 서버에서 localhost는?

  • DB 없음
  • 서비스 다운
  • 장애 알림 폭탄

실제 현업에서 매년 반복되는 사고..


📌 핵심 정리

문제 원인 결과
보안 사고 비밀정보가 코드에 있음 해킹, 정보 유출
환경 관리 실패 환경마다 코드 수정 버그 증가
협업 충돌 개인 설정이 커밋됨 팀 생산성 하락
이력 오염 설정과 로직 혼합 변경 추적 불가
운영 장애 환경 분리 실패 서비스 중단

✅ 반드시 기억해야 할 원칙

코드와 설정은 절대 섞지 않는다
  • 코드 → “무엇을 할지”
  • 설정 → “어디서, 어떻게 할지”

이 원칙을 지키기 위해 등장한 것이 바로 .env 파일과 환경변수 관리다.


🔐 환경변수 관리 방법 총정리 (.env부터 Secrets Manager까지)

✅ 결론 먼저 (TL;DR)

  • 로컬 개발 / 개인 프로젝트: .env (+ .env.example)
  • 서버 1~2대, 간단 배포: OS 환경변수
  • Docker/쿠버 기반 배포: 컨테이너 env + (민감정보는 Secret)
  • 보안이 중요 / 클라우드 쓰는 팀: Secrets Manager 계열
  • 대규모 조직 / 중앙 통제: Vault 같은 전용 비밀관리

🧠 핵심 개념

1) “환경변수”는 그냥 문자열 박스가 아니다

환경변수는 코드 밖에서 프로그램에게 주는 설정값이다.
중요한 것은..

  • 코드(Code) = 무엇을 할지 (로직)
  • 설정(Config) = 어디서/어떻게 할지 (DB 주소, 키, 토큰, 모드 등)

둘을 섞으면?

배포할 때마다 코드 수정 → 커밋 오염 → 실수 → 장애
(콤보 오픈)


2) Config vs Secret 구분 못 하면 팀이 고생한다

구분예시특징관리 전략
ConfigDB_HOST, PORT, LOG_LEVEL노출돼도 치명적이지 않은 값.env / 설정파일 / 환경변수
SecretDB_PASSWORD, API_KEY, JWT_SECRET노출되면 서비스 끝장날 수 있음Secrets Manager / Vault / K8s Secret

🗺️ 선택 가이드

환경변수 관리 방식 선택 흐름

[시작]
  |
  v
프로젝트 규모는?
  |
  +--> 개인/소규모 ---------------------+
  |                                  |
  |                              보안 중요?
  |                                  |
  |                      +-----------+-----------+
  |                      |                       |
  |                      v                       v
  |                 낮음(.env)          높음(Secrets Manager)
  |
  +--> 팀/중간 규모 -----------------------------+
  |                                           |
  |                                       배포 형태?
  |                                           |
  |                      +--------------------+--------------------+
  |                      |                                         |
  |                      v                                         v
  |               서버 직접 배포(OS env)                   컨테이너(Docker/K8s)
  |
  +--> 대규모/규정 빡셈 ---------------------------------> Vault / 중앙 비밀관리

🧰 방법별 정리 (장단점 + 언제 쓰는지)

방법추천 상황장점단점보안
.env로컬 개발, 소규모세팅 빠름, 직관적유출 위험(실수로 커밋)낮음
OS 환경변수서버 직접 운영파일 없이 관리, CI/CD 연계 쉬움서버 여러 대면 반복 작업중간
설정 파일(JSON/YAML)계층 구조 설정 필요구조 표현 강함Secret 넣으면 바로 지뢰낮음~중간
Docker/K8s env컨테이너 배포배포 파이프라인과 찰떡Secret 관리 따로 해야 함중간~높음
Secrets Manager클라우드 + 보안 중요권한제어/로깅/회전(rotate)비용/세팅 필요높음
Vault대규모 조직중앙 통제, 강력한 정책운영 난이도 높음매우 높음

🧪 실전 예시 모음

1) .env (로컬 개발)

  • .env무조건 .gitignore
  • .env.example 만들어서 키 목록만 공유
  • 로컬은 .env, 운영은 OS env / Secret로 주입하는 식으로 역할 분리
# .env (절대 커밋하지 말기)
APP_ENV=local
DB_HOST=localhost
DB_PORT=5432
DB_USER=admin
DB_PASSWORD=supersecret

# .env.example (이건 커밋 OK - 값은 더미로)
APP_ENV=local
DB_HOST=localhost
DB_PORT=5432
DB_USER=admin
DB_PASSWORD=CHANGEME
# Python에서 읽기 (python-dotenv)
# pip install python-dotenv

import os
from dotenv import load_dotenv

load_dotenv()

DB_HOST = os.getenv("DB_HOST")
DB_PASSWORD = os.getenv("DB_PASSWORD")

print(DB_HOST)

2) OS 환경변수 (서버 직접 배포)

# Linux/Mac
export APP_ENV=prod
export DB_HOST="prod.db.internal"
export DB_PASSWORD="xxxxx"

# 영구 적용(예: bash)
echo 'export DB_HOST="prod.db.internal"' >> ~/.bashrc
source ~/.bashrc

운영에서 이 방식이 좋은 이유는 단순하다.

  • “코드”는 그대로 두고
  • “환경”만 바꿔서 실행 가능

3) Docker / Kubernetes (컨테이너 배포)

Docker: 실행 시 주입

docker run \
  -e APP_ENV=prod \
  -e DB_HOST=prod.db.internal \
  -e DB_PASSWORD=xxxxx \
  myapp:latest

--env-file 사용:

docker run --env-file ./production.env myapp:latest

Kubernetes: ConfigMap vs Secret (구분 필수)

(개념)
ConfigMap = 일반 설정
Secret    = 민감정보

K8s에서 컨테이너로 값 주입 흐름:

[ConfigMap/Secret]
      |
      v
(Deployment env)
      |
      v
[Container ENV]
      |
      v
app이 os.getenv()로 읽음
# secret.yaml
# 주의: 기본 K8s Secret은 "암호화"가 아니라 base64 인코딩 수준임

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  password: c3VwZXJzZWNyZXQ=  # "supersecret" (base64)
# deployment.yaml (Secret 주입)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
        - name: myapp
          image: myapp:latest
          env:
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: password

4) Secrets Manager (진짜 “비밀”은 여기로)

Secret을 파일(.env)로 들고 다니면 항상 “실수로 커밋” 지뢰가 남는다.
Secrets Manager 계열은 보통 아래 3개가 핵심이다:

  • 권한 제어: 누가 가져갈 수 있는지 제한
  • 감사 로그: 누가 언제 접근했는지 기록
  • 회전(Rotation): 비밀번호 자동 교체 가능
# (예시) AWS Secrets Manager - 개념 코드
# boto3 사용

import json
import boto3

client = boto3.client("secretsmanager", region_name="ap-northeast-2")

response = client.get_secret_value(SecretId="my-db-credentials")
secrets = json.loads(response["SecretString"])

db_password = secrets["password"]
print(db_password)

🧩 실무에서 자주 터지는 포인트

1) “우선순위” 를 정해둬야 덜 싸운다

추천 우선순위

1) 실행 시 주입된 환경변수 (가장 우선)
2) Secrets Manager/Vault에서 가져온 값
3) .env (로컬 개발 편의)
4) 코드 기본값(default)

이렇게 해두면:
- 운영: 1,2로만 굴러감
- 로컬: 3으로 편하게 개발
- 누락: 4로 최소한의 기본 동작

2) “설정 변경 = 재배포 없이 반영”은 환상인 경우가 많다

  • 환경변수는 보통 프로세스 시작 시 읽는다
  • 즉, 값 바꾸면 재시작/롤링배포가 필요할 때가 많다
  • “런타임에 바뀌는 설정”이 필요하면
    별도 설정 서버/DB/Feature Flag로 풀어야 한다

3) 절대 하지 말 것 3개

1) 비밀번호/API 키를 코드에 하드코딩
2) .env를 커밋 (또는 스크린샷/블로그에 노출)
3) 설정값 바꾸려고 운영 코드를 수정해서 배포

✅ 마무리

코드는 “무엇을” 담고, 설정은 “어디서/어떻게” 담는다.
둘을 섞는 순간, 장애는 “언젠가”가 아니라 “곧” 온다.


🎯 체크리스트

  • ☑ Secret과 Config 구분했나?
  • .env는 gitignore 처리했나?
  • ☑ 팀 공유는 .env.example로 하고 있나?
  • ☑ 운영 비밀정보는 Secrets Manager/Vault/K8s Secret으로 주입하나?
  • ☑ 우선순위(Precedence) 룰이 문서화돼 있나?
profile
Gongbuhaja

0개의 댓글