buildrisk-radar

ADR-031 AWS 데모 배포 — RDS(비-superuser 소유자) · 앞단 프록시 IP 신뢰 · 조회 전용 공개

배경

포트폴리오 공개용으로 Macro · Wakeline 과 함께 AWS 서울 리전에 올린다. 구성은 다음과 같다.

로컬 구성을 그대로 올리면 다음이 맞지 않았다.

  1. RDS 소유자는 superuser가 아니다. RDS 마스터도 rds_superuser일 뿐이고, Flyway 소유자 buildrisk는 CREATEROLE만 가진다. 그런데 afterMigrate.sql이 기동할 때마다 ALTER ROLE buildrisk_app … NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION을 실행한다. PG16+는 superuser가 아니면 이 속성들을 적는 것만으로 거절한다. 그래서 첫 기동은 되고 두 번째 기동부터 api가 뜨지 않는다(VERIFICATION 169).
  2. 클라이언트 IP: edge가 X-Forwarded-For를 직접 접속 주소로 덮어쓴다. Caddy 뒤에서는 모든 방문자가 한 주소로 보여 IP당 레이트리밋 · 로그인 잠금이 방문자 전체에 걸린다.
  3. 공개 데모의 위험: 로그인 무차별 대입, 규칙 변경, 배치 실행(외부 API 호출), 웹훅이 남아 있다. 배치 스케줄은 새벽(02–05시 · 18:30)이라 운영 시간에는 돌지 않는다.

결정

  1. afterMigrate.sql: 역할이 이미 있으면 LOGIN PASSWORD만 맞춘다. 누가 속성(superuser · createdb · createrole · replication · bypassrls)을 올려 두었을 때만 NO…로 내린다. superuser가 아니면 그 문장에서 실패해 기동이 멈춘다. 최소 권한이 깨진 채 뜨지 않게 하려는 것이다.
  2. 덧붙임 파일 compose.aws.yml: docker-compose.yml(로컬)은 바꾸지 않는다.
    • db는 profile로 빼고, RDS에는 sslmode=require로 붙는다. PostGIS는 RDS 마스터가 미리 설치한다(aws-deploy rds/bootstrap.sql).
    • Flyway 비밀번호는 기본값 없이 필수다.
    • Hikari 풀은 12에서 4로 줄인다.
    • 웹훅을 끄고(NOTIFY_SECRET_KEY 비움), 배치 스케줄도 끈다.
  3. edge realip: nginx.conf에 include /etc/nginx/edge.d/*.conf;를 둔다(로컬에서는 비어 있어 아무 일도 하지 않는다).
    • AWS에서는 ops/nginx/realip.aws.conf를 마운트한다. 사설 대역(도커 브리지 게이트웨이)에서 온 X-Forwarded-For를 믿는다.
    • realip이 $remote_addr 자체를 바꾸므로 api 쪽(TRUSTED_PROXY_REGEX = edge 고정 IP)은 그대로다.
  4. 조회 전용 공개: 앞단 Caddy가 /api/ 아래 GET · HEAD가 아닌 요청을 403으로 막는다(로그인 포함). 관리자는 SSM 포트 포워딩으로 edge(127.0.0.1:3400)에 직접 붙는다.
  5. 데이터 이전: 실행 스크립트로 처음부터 적재(1–2시간, DART 5,349회)하지 않고 로컬 DB를 덤프해 복원한다.
    • pg_dump -Fc --no-owner --no-privileges로 뜬다. 로컬 이미지가 자동으로 넣은 확장(postgis · postgis_topology · postgis_tiger_geocoder · fuzzystrmatch)과 그 스키마(topology · tiger · tiger_data)는 뺀다.
    • 복원은 pg_restore --no-owner --no-privileges로 하고 소유자 계정으로 실행한다. flyway_schema_history가 함께 오므로 Flyway는 V21을 최신으로 본다.

이유

대안과 버린 이유

결과(검증)

덧붙임 (2026-10-11, VERIFICATION 171) — 공개 데모 화면에서 로그인 안내를 숨김 결정 4로 공개 주소의 로그인 POST 는 앞단에서 403 이 된다. 그런데 화면은 머리말의 [로그인] 링크와 관리 화면의 ‘관리자 로그인 후 변경할 수 있습니다 · 로그인’ 안내를 그대로 보였다 — 누르면 로그인 화면까지는 가지만 로그인은 할 수 없다.

덧붙임 (2026-10-11, VERIFICATION 179 · 181) — 쿠키 Secure 를 고정하지 않은 이유 · 테스트 DB 를 운영과 같게