Files
comrelay/.env.production.example
T
ttipo 8d00d71072 feat: PC 데스크톱 알림(웹 푸시) 추가 — 인앱/SSE에 OS 토스트 연동
카카오톡처럼 PC에 OS 토스트가 뜨도록 Web Notifications(Level1) +
Web Push/서비스워커(Level2)를 기존 인앱·SSE 알림 위에 얹는다.
중복 방지: 페이지가 열려 있으면 SSE 로컬 알림(포커스면 인앱만),
닫혀 있으면 서비스워커 푸시가 담당한다.

- 백엔드: push_subscriptions 엔티티 + WebPushService(VAPID 설정·
  type→{title,body,url} 포매터·만료 구독 정리), notify()가 SSE와
  함께 푸시 발송, push/subscribe·unsubscribe 엔드포인트, 마이그레이션,
  web-push 의존성
- 프론트: public/sw.js(push/클릭), usePush 컴포저블(권한·구독, 결과
  안내), notification.store 로컬 토스트, AppShell 'PC 알림 켜기' 버튼
- env/compose: VAPID 키 주입(공개키→프론트, 비밀키→백엔드)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 00:49:33 +09:00

91 lines
3.8 KiB
Bash

# ==========================================
# 루트 .env (production) — 모든 설정의 단일 진실 공급원(SSOT)
# docker-compose 가 이 값을 backend/frontend/db/redis 에 주입한다.
# .example 을 복사해 만들고 실제 값으로 채운다. (커밋 금지)
# ==========================================
# ==========================================
# 프로젝트 전역
# ==========================================
PROJECT_NAME=comrelay
APP_ENV=production
BUILD_MODE=production
FRONTEND_DIR=frontend
BACKEND_DIR=backend
# ==========================================
# 포트
# ==========================================
FRONTEND_PORT=80
BACKEND_PORT=3000
WEBSOCKET_PORT=3001
DB_PORT=5432
REDIS_PORT=6379
# ==========================================
# Database (PostgreSQL)
# ==========================================
DB_IMAGE=postgres:15-alpine
DB_USER=prd_ttipo
DB_PASSWORD=change-me-db-password
DB_NAME=comrelay_db
DB_DATA_DIR=./data/postgres
# ==========================================
# Redis
# ==========================================
REDIS_IMAGE=redis:7-alpine
REDIS_PASSWORD=change-me-redis-password
REDIS_DATA_DIR=./data/redis
# ==========================================
# API 경로
# ==========================================
# BACKEND_API_URL: 프론트 빌드에 주입(VITE_API_BASE_URL) — 운영 도메인으로 교체
# CORS_ORIGIN : 백엔드가 허용할 프론트 오리진 — 운영 도메인으로 교체
BACKEND_API_URL=http://localhost:3000/api
CORS_ORIGIN=http://localhost:5173
# ==========================================
# AI (백엔드·프론트 공통)
# ==========================================
# AI_TIMEOUT_MS: AI 요청 타임아웃(ms). 백엔드 Claude 호출 abort + 프론트 axios 에 동일 적용.
# 프론트에는 build arg VITE_AI_TIMEOUT_MS 로 주입된다.
AI_TIMEOUT_MS=60000
# ==========================================
# 화상회의 (LiveKit) — 셀프호스팅(기본) / Cloud(대안)
# ==========================================
# [셀프호스팅] 운영 권장. 절차: livekit/DEPLOY.md (단일노드 3장, AWS EC2+도커 nginx 4-1장).
# - selfhost-livekit 프로파일로 컨테이너 기동:
# docker compose --profile selfhost-livekit --env-file .env.production up -d --build
# - 리버스 프록시(wss 종단)는 livekit/nginx.livekit.conf.example 참고.
# - 키 생성(절대 Cloud 키 재사용 금지):
# LIVEKIT_API_KEY=$(openssl rand -hex 8)
# LIVEKIT_API_SECRET=$(openssl rand -hex 32) # 최소 32자
# - LIVEKIT_WS_URL : 브라우저 접속(리버스 프록시 TLS) → wss://livekit.<운영도메인>
# - LIVEKIT_URL : 백엔드 → LiveKit 내부 API(도커 네트워크) → http://livekit:7880
# [Cloud] 대안. LIVEKIT_WS_URL/URL 을 wss://<project>.livekit.cloud 로, 키를 Cloud 값으로
# 채우고 selfhost-livekit 프로파일은 켜지 않는다.
LIVEKIT_API_KEY=change-me-livekit-key
LIVEKIT_API_SECRET=change-me-livekit-secret-min-32-characters
LIVEKIT_WS_URL=wss://livekit.example.com
LIVEKIT_URL=http://livekit:7880
# ==========================================
# 드라이브 (NCP Object Storage / S3 호환)
# ==========================================
# 운영 버킷은 개발과 분리한다(예: comrelay-prod). 비시크릿만 루트에 두고
# ACCESS/SECRET 키는 backend/.env.production 에 둔다.
# OBJECT_STORAGE_ENDPOINT : NCP 리전 엔드포인트(서울: https://kr.object.ncloudstorage.com)
# OBJECT_STORAGE_REGION : 리전명(NCP: kr-standard)
# OBJECT_STORAGE_BUCKET : 운영 버킷명
OBJECT_STORAGE_ENDPOINT=https://kr.object.ncloudstorage.com
OBJECT_STORAGE_REGION=kr-standard
OBJECT_STORAGE_BUCKET=comrelay-prod
# 웹 푸시 알림 (Web Push / VAPID) — 비밀 아닌 값만 루트에서 주입
# 키페어 생성: node -e "console.log(require('web-push').generateVAPIDKeys())"
VAPID_PUBLIC_KEY=
VAPID_SUBJECT=mailto:admin@example.com