# ============================================================================== # docker/docker-compose.yaml — MAM 원격 프로덕션 브로커 (Track 1R) # 정본 문서: PRIVATE_SERVER.md §9.2 # # 사용법: cd docker && cp .env.example .env && <시크릿 채우기> && docker compose up -d # ============================================================================== services: nats: image: nats:2.12-alpine # alpine 필수: healthcheck 의 wget 이 여기에만 있음 container_name: mam-nats restart: unless-stopped command: ["-c", "/etc/nats/nats.conf"] environment: # 미설정/빈 값이면 컨테이너 생성 전에 compose 가 중단 → fail-closed MAM_BROKER_PASS: ${MAM_BROKER_PASS:?set MAM_BROKER_PASS in docker/.env} MAM_OBSERVER_PASS: ${MAM_OBSERVER_PASS:?set MAM_OBSERVER_PASS in docker/.env} HOME_BROKER_PASS: ${HOME_BROKER_PASS:?set HOME_BROKER_PASS in docker/.env} SYS_BROKER_PASS: ${SYS_BROKER_PASS:?set SYS_BROKER_PASS in docker/.env} ports: # ⚠ Docker 의 published 포트는 UFW 를 우회합니다. 노출 통제는 방화벽이 아니라 # 여기의 바인드 주소가 담당합니다. 기본값은 전부 loopback. - "${MQTT_BIND:-127.0.0.1}:1883:1883" # MQTT 3.1.1 (평면 A: MAM) - "${NATS_BIND:-127.0.0.1}:4222:4222" # NATS 네이티브 (평면 B) - "127.0.0.1:8222:8222" # 무인증 모니터링 — loopback 고정 - "${WS_BIND:-127.0.0.1}:8080:8080" # WebSocket (NATS + /mqtt 경로의 MQTT) volumes: - ./nats.conf:/etc/nats/nats.conf:ro - nats-data:/data # nats.conf 의 store_dir 와 일치 healthcheck: test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:8222/healthz"] interval: 30s timeout: 5s retries: 3 start_period: 20s logging: driver: json-file options: { max-size: "10m", max-file: "3" } volumes: nats-data: