환경변수 카탈로그
.env.example에 정의된 모든 환경변수와 영향 범위를 그룹별로 정리합니다.
시크릿 회전 시 영향 매트릭스는 본 페이지가 아니라
시크릿 회전에서 단일 출처로 관리합니다.
인증 / 암호화
| 변수 | 기본값 | 설명 |
|---|---|---|
AUTH_SECRET_KEY | (필수, 빈값 금지) | JWT 서명 키. 회전 시 모든 활성 세션 무효 |
ENCRYPTION_SALT | (필수, 빈값 금지) | server/auth/crypto.py Fernet 키 파생 솔트. 거래소 API 키 + KIS 계좌번호 암복호화 |
LIVE_CONFIRM_SECRET | 빈값 시 AUTH_SECRET_KEY 폴백 | paper→live 승급 HMAC 시크릿 |
RECAPTCHA_SECRET_KEY | (옵션) | reCAPTCHA v3. 빈값이면 검증 스킵 (개발용) |
데이터베이스 / 캐시
| 변수 | 기본값 | 설명 |
|---|---|---|
DATABASE_URL | postgresql+psycopg://quant:quant@localhost:5432/quantai | TimescaleDB 접속. 드라이버는 반드시 postgresql+psycopg:// (psycopg v3) |
DB_USER / DB_PASSWORD / DB_NAME | quant / 필수 / quantai | docker-compose.prod.yml 가 빈 DB_PASSWORD를 거부 |
REDIS_URL | redis://localhost:6379/0 | 분석 큐 + WebSocket pubsub + rate limit |
거래소 — Crypto (CCXT)
| 변수 | 설명 |
|---|---|
EXCHANGE_API_KEY | Binance/Bybit/OKX API 키. 개발용 폴백. 사용자별 키는 DB의 암호화 컬럼으로 관리 |
EXCHANGE_API_SECRET | 위 키의 시크릿 |
사용자별 거래소 키는 DB에 저장
환경변수의 EXCHANGE_*는 시스템 폴백 / 개발 편의용이며, 운영에서는 사용자가
UI에서 직접 등록한 키가 exchange_keys 테이블에 Fernet으로 암호화되어
저장됩니다. 자세한 내용은
설정 — 거래소 키 참조.
거래소 — US Equity (Alpaca)
| 변수 | 기본값 | 설명 |
|---|---|---|
ALPACA_API_KEY | (옵션) | 시스템 폴백 |
ALPACA_SECRET_KEY | (옵션) | 위 키의 시크릿 |
ALPACA_BASE_URL | https://paper-api.alpaca.markets | 페이퍼 / 라이브 분리 — 라이브는 https://api.alpaca.markets |
ALPACA_DATA_URL | https://data.alpaca.markets | 시장 데이터 엔드포인트 |
거래소 — KR Equity (KIS)
| 변수 | 기본값 | 설명 |
|---|---|---|
KIS_APP_KEY | (옵션) | 한국투자증권 OpenAPI App Key. 사용자별 키는 DB |
KIS_APP_SECRET | (옵션) | App Secret |
KIS_ACCOUNT_NO | (옵션) | 계좌번호 (Fernet 암호화 컬럼으로 저장) |
KIS_PRODUCT_CODE | (옵션) | 상품 코드 (보통 01) |
KIS_BASE_URL | https://openapivts.koreainvestment.com:29443 | 모의투자. 실투자는 https://openapi.koreainvestment.com:9443 |
KIS_HASHKEY_URL | (옵션) | hashkey 엔드포인트 오버라이드 |
KIS 토큰은 24h 만료이며, KISTokenManager가 자동 갱신합니다 — 자세한
내용은 KIS 토큰 만료 참조.
Feature flags
| 변수 | 기본값 | 의미 |
|---|---|---|
FEATURE_EQUITY_PAPER | false | 미국/한국 주식 페이퍼 모드 라우트 활성 |
FEATURE_EQUITY_LIVE | false | 라이브 모드. ALLOW_LIVE=1 동시 만족 필요 (prod) |
FEATURE_LLM_ANALYSIS | false | LLM 분석 라우트 활성 (/api/equity/analyze) |
FEATURE_KIS_BROKER | false | KIS 브로커 어댑터 활성 |
FEATURE_ALPACA_BROKER | false | Alpaca 브로커 어댑터 활성 |
FEATURE_EQUITY_ANALYSIS | false | Equity 페이지 분석 탭 활성 |
세부 의미와 의존 관계는 피처 플래그 참조.
LLM (LiteLLM proxy, OpenAI 호환)
| 변수 | 기본값 | 설명 |
|---|---|---|
OPENAI_BASE_URL | (옵션) | LiteLLM proxy URL. 빈값이면 OpenAI 직결 |
OPENAI_API_KEY | (옵션) | LiteLLM master key 또는 OpenAI 키 |
OPENAI_MODEL_DEFAULT | gpt-4o-mini | 기본 분석 모델 |
OPENAI_MODEL_DECISION | gpt-4o | 의사결정용 모델 (비싸지만 정확) |
LLM_TIMEOUT_SECONDS | 60 | 단일 호출 타임아웃 |
LLM_MAX_RETRIES | 3 | 5xx/timeout 재시도 횟수 |
LLM_DAILY_BUDGET_USD | 5.00 | 일일 예산 한도. 초과 시 분석 차단 |
알림 / 모니터링
| 변수 | 기본값 | 설명 |
|---|---|---|
TELEGRAM_TOKEN | (옵션) | Telegram 봇 토큰. 빈값이면 알림 비활성 (거래는 무영향) |
TELEGRAM_CHAT_ID | (옵션) | 알림 채팅방 ID |
GRAFANA_URL | http://localhost:3000 | Grafana 외부 URL (이메일 알림 본문 등) |
GRAFANA_WEBHOOK_URL | http://api:8000/internal/grafana/webhook | Grafana → API 알림 브리지 |
GRAFANA_WEBHOOK_SECRET | (옵션) | Bearer 토큰. 둘 다 비워두면 무인증 (로컬만 권장) |
GF_SECURITY_ADMIN_USER | admin | Grafana 관리자 계정 |
GF_SECURITY_ADMIN_PASSWORD | admin | 첫 부팅 후 즉시 변경 |
OPS_EMAIL | ops@example.com | 일일 손실 임박 등 critical 알림 수신 |
라이브 모드 게이팅 (P4-01)
| 변수 | 기본값 | 설명 |
|---|---|---|
ALLOW_LIVE | (빈값=차단) | VM 호스트 환경변수. 1이어야 FEATURE_EQUITY_LIVE가 적용됨 |
LIVE_DAILY_TRADE_LIMIT | 10 | 사용자별 일일 라이브 주문 상한 (UTC 자정 리셋) |
RISK_PAPER_MIN_DAYS | 90 | 라이브 승급에 필요한 최소 페이퍼 운용 일수 |
RISK_PAPER_MIN_TRADES | 50 | 라이브 승급에 필요한 최소 페이퍼 거래 수 |
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS / SMTP_SENDER | (옵션) | 라이브 승급 confirm-email 발송. 빈값이면 토큰을 로그로만 남김 |
데이터 소스 — Equity
| 변수 | 기본값 | 설명 |
|---|---|---|
YFINANCE_ENABLED | true | yfinance 데이터 백엔드 사용 여부 |
DART_API_KEY | (옵션) | 한국 공시(DART) API 키. LLM 분석 품질만 영향 |
FRED_API_KEY | (옵션) | 매크로 (FRED) API 키 |
워커 튜너블
analysis-worker:
| 변수 | 기본값 | 설명 |
|---|---|---|
ANALYSIS_WORKER_CONCURRENCY | 3 | 한 워커당 동시 처리 작업 수 |
ANALYSIS_WORKER_LEASE_SECONDS | 300 | 큐 lease 만료 시간 |
ANALYSIS_WORKER_POLL_INTERVAL | 5 | 큐 폴링 주기 (초) |
ANALYSIS_WORKER_MAX_ATTEMPTS | 3 | 작업 최대 재시도 횟수 |
position-reconciler:
| 변수 | 기본값 | 설명 |
|---|---|---|
RECONCILER_POLL_INTERVAL_SECONDS | 300 | 5분 주기 |
RECONCILER_TOLERANCE_PCT | 0.01 | 1% 미만 차이는 info |
RECONCILER_CRITICAL_PCT | 0.05 | 5% 이상 차이 → emergency_stop |
RECONCILER_MAX_CONCURRENT_USERS | 5 | 한 사이클당 동시 검사 사용자 수 |
자세한 운영 튜닝은 포지션 리컨실러 참조.
검증
# 컨테이너 안에서 실제 적용된 값 확인
docker compose exec api env | grep -E '^(FEATURE_|RISK_|LIVE_|ANALYSIS_|RECONCILER_)' | sort
# 시크릿이 placeholder 값이 아닌지 확인 (none 출력이 정상)
docker compose exec api python -c "
import os
secs = ['AUTH_SECRET_KEY', 'ENCRYPTION_SALT']
for s in secs:
v = os.environ.get(s, '')
bad = v in {'', 'changeme', 'change-me', 'your_secret_here'}
print(f'{s}: {\"BAD\" if bad else \"ok\"}')"