Metabase를 Supabase에 안전하게 연결하기 – Read-Only Role, RLS Policy

🧭 상황 Supabase에 저장된 데이터를 시각화하기 위해 Metabase 대시보드를 셋업 🔒 Metabase 연결 시 보안 옵션 옵션 1. EC2 보안 그룹에서 IP 화이트리스트 설정 집 또는 사무실 IP만 인바운드 접근 허용 효과: 오직 본인만 Metabase 로그인 페이지에 접근 가능 단점: 이동 중이거나 다른 네트워크를 사용할 때마다 규칙을 갱신해야 함 옵션 2. 리버스 프록시 + 기본 인증 (Basic Auth) 적용 같은 EC2 인스턴스에 Nginx 리버스 프록시를 실행 Nginx에서 다음을 처리: HTTPS (TLS 인증서) Metabase 진입 전 추가 비밀번호 게이트 외부에는 443(HTTPS) 포트만 노출하고, 3000 포트는 비공개 ...

10월 29, 2025

Postgres FTS와 dbt 인덱스로 빠르고 정확한 검색 만들기

이번 글에서는 내가 KBooks 사이트에 검색 기능을 처음 추가했던 과정을 공유한다. 국립중앙도서관 API에서 수집한 모든 도서 데이터는 이미 dbt 파이프라인을 통해 Supabase(Postgres) 로 들어오고 있었다. 이제 검색을 붙여보겠다. 아래는 데이터베이스 수준에서 검색을 준비한 단계별 과정과, 각각의 결정이 왜 타당했는지에 대한 설명이다. 1. 깨끗한 출발점: silver_books 원본 데이터는 raw_nl_books에 JSON 형태로 저장된다. 여기서 dbt를 통해 silver_books 테이블을 만들었고, 각 행은 ISBN-13으로 식별되는 고유한 책 하나를 나타낸다. 유효한 ISBN만 남겨 중복을 제거했다. ...

10월 23, 2025

Spark → Kafka → Postgres 파이프라인에서 UUID가 터트린 지뢰

Kafka와 Spark Structured Streaming을 이용해서 데이터 파이프라인을 구축하고 있었습니다. 완전히 컨테이너화된 시스템. 스택 구성은 이렇습니다: Kafka → 거래 데이터를 스트리밍으로 전송 Spark Structured Streaming → 실시간 처리 및 이상 거래 탐지 Postgres → 데이터 웨어하우스 모든 게 순조로웠습니다. 그런데 갑자기 등장한 한 놈. UUID 필드. 맞습니다 — UUID. 이제 어떤 일이 벌어졌는지 정확히 보여드릴게요. ✅ 원래 설계 Postgres 테이블을 이렇게 설계했죠: CREATE TABLE fact_transaction ( transaction_id UUID PRIMARY KEY, customer_id UUID REFERENCES dim_customer(customer_id), merchant_id UUID REFERENCES dim_merchant(merchant_id), ... ); Kafka는 UUID를 문자열로 직렬화해서 이벤트를 잘 뿌려주고 있었습니다 (JSON은 원래 UUID 타입이 없으니까요). ...

6월 7, 2025

🔧 Airflow Docker 스타트 문제 해결

Airflow를 Docker로 운영하면서 자주 마주치는 이슈를 정리 ❗ 문제 1 — .env 파일이 Airflow 컨테이너 안에서 안 보인다 🔍 증상 요약 .env 파일은 프로젝트 루트에 존재. 하지만 Airflow 컨테이너 안에서는 load_dotenv()가 읽지 못함. 이유: Docker는 .env 파일을 환경변수로 변환해 넘기긴 하지만, 파일 자체를 컨테이너 내부로 복사하거나 mount하지 않는다. 결국 load_dotenv()가 찾을 파일이 없음. ✅ 해결법 1️⃣ docker-compose.yml에 volume mount 추가 services: airflow: ... volumes: - ./dags:/opt/airflow/dags - ./.env:/opt/airflow/dags/.env # ✅ 이 줄 추가 이렇게 하면 .env 파일이 Airflow 컨테이너 안의 /opt/airflow/dags/.env 경로로 복사된다. ...

5월 30, 2025