🧚 왜 dbt를 Airflow Docker 컨테이너 안에서 실행하는가

데이터 엔지니어링 파이프라인에서 dbt와 Airflow는 종종 함께 사용된다. 여기서 자주 마주하는 설계 결정이 있다: dbt를 Airflow와 어떻게 함께 실행할 것인가? dbt를 별도의 컨테이너에서 실행하고 API나 CLI 호출로 오케스트레이션할 것인가? 아니면 dbt를 Airflow의 Docker 컨테이너 안에서 직접 실행할 것인가? 둘 다 실험해본 결과, dbt를 Airflow 컨테이너 안에서 실행하는 방식을 선호한다. 이유는 다음과 같다. ✅ 하나의 컨테이너 = 하나의 환경 Airflow DAG가 동일한 컨테이너 안에서 dbt 명령어를 직접 실행한다. 이를 통해 다음이 보장된다: 동일한 Python 버전 동일한 dbt 버전 동일한 의존성 버전 (dbt 패키지, 어댑터) 컨테이너 간 네트워킹 이슈 없음 별도의 컨테이너로 분리할 경우 다음을 관리해야 한다: ...

6월 4, 2025

🧹 데이터 클렌징: 왜 스테이징 레이어에서 클렌징을 해야 하는가

실제 데이터 엔지니어링 파이프라인에서 가장 흔한 실수 중 하나는 데이터 클렌징을 너무 뒤로 미루는 것입니다. 업스트림 데이터가 깨끗할수록 다운스트림 모델은 더 단순하고 유지보수하기 쉬워집니다. 이제 하나씩 살펴보겠습니다. ✅ 기본 원칙 가능한 한 가장 이른 단계에서 데이터를 클렌징 — 이상적으로는 스테이징 레이어에서 처리해야 합니다. ✅ 그 이유 1️⃣ 책임 분리의 명확성 스테이징 모델의 역할은 다음과 같습니다: 클렌징 표준화 (정규화) 타입 캐스팅 만약 더러운 데이터를 marts까지 (예: dim_customer, fct_transaction) 넘긴다면: 다운스트림 모델이 복잡해짐 중복 필터 발생 유지보수가 어려운 취약한 코드 생성 2️⃣ Marts 레이어는 비즈니스 로직만 담당해야 한다 Marts 레이어는 오직 다음에 집중해야 합니다: ...

6월 4, 2025

🐳 GitHub Pages용 Jekyll 블로그를 Docker로 세팅하기 — 삽질 끝에 완성한 깔끔한 구성

😩 문제 Jekyll을 Docker로 세팅하는 건 쉬워 보였지만, 실제로는 여러 문제를 겪었습니다: 플랫폼 이슈 (arm64 vs amd64) - Apple Silicon Macbook (M1)을 사용중 bundle install에서 발생하는 오류들 개인 GitHub Pages 사이트용으로 만들고 있었기 때문에, GitHub Pages에서 사용하는 gem 버전과 호환되면서도 로컬에서 개발하기 쉽게 유지해야 했습니다. 🛠 나의 깔끔한 해결책 결국 이 Docker 세팅을 만들게 되었습니다. 저에게는 잘 작동합니다. ✅ Key Features Apple Silicon (M1/M2)와 Intel 모두에서 동작 깔끔하게 다시 빌드 가능한 이미지 볼륨 마운트를 통한 안정적인 파일 동기화 GitHub Pages의 Jekyll 버전과 호환 (선택 사항) livereload 지원 🐳 The Dockerfile FROM ruby:3.2.3-slim RUN apt-get update -qq && \ apt-get install -y build-essential libpq-dev nodejs npm RUN gem install bundler -v 2.6.9 WORKDIR /srv/jekyll COPY Gemfile* ./ RUN bundle install COPY . . EXPOSE 4000 CMD ["bundle", "exec", "jekyll", "serve", "--host", "0.0.0.0", "--force_polling", "--livereload"] 🐳 docker-compose.yml services: site: image: my-jekyll platform: linux/arm64 command: bundle exec jekyll serve --host 0.0.0.0 --force_polling --livereload ports: - "4000:4000" - "35729:35729" volumes: - .:/srv/jekyll - ./vendor/bundle:/usr/local/bundle working_dir: /srv/jekyll environment: - JEKYLL_ENV=development 💎 Gemfile source "https://rubygems.org" gem "jekyll", "~> 4.3.3" gem "csv", "~> 3.3.5" gem "base64", "~> 0.2.0" gem "logger", "~> 1.6.0" group :jekyll_plugins do gem "jekyll-feed", "~> 0.17.0" gem "jekyll-seo-tag", "~> 2.8.0" end # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem # and associated library. platforms :mingw, :x64_mingw, :mswin, :jruby do gem "tzinfo", ">= 1", "< 3" gem "tzinfo-data" end # Performance-booster for watching directories on Windows gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] # Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem # do not have a Java counterpart. gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby] # Add webrick as it's no longer bundled with Ruby gem "webrick", "~> 1.8" Gemfile.lock도 레포에 포함되어 있습니다. ...

6월 3, 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

🔧 ARM Mac + Docker + dbt 시작 트러블 슈팅

Airflow + dbt 프로젝트를 Docker로 세팅하던 중 발생하는 에러 메시지와 해결법. 🔍 문제1 : 플랫폼 아키텍처 mismatch 에러 메시지: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) 내 Mac은 ARM (Apple Silicon - M1/M2/M3) dbt 공식 도커 이미지는 기본적으로 amd64 (x86 기반) 결국 도커가 내부적으로 qemu 에뮬레이션을 돌리다가 Python 경로 꼬임까지 발생 → dbt dbt --version 오류로 드러남. 이건 단순 dbt 오류가 아니라 플랫폼 mismatch가 근본 원인입니다. ...

5월 30, 2025

🔧 왜 Airflow는 init, scheduler, webserver를 따로 띄울까?

Airflow 조금 만지다 보면, 대부분 이렇게 서비스가 나뉘어 돌아가는 걸 보게 됩니다. airflow-init airflow-scheduler airflow-webserver “이걸 굳이 왜 이렇게 쪼개?” 라는 생각이 들 수 있는데요. 이게 바로 실전 운영 방식입니다. 1️⃣ airflow-init — 준비 담당 다른 이름으로 airflow-db-migrate 나 airflow-bootstrap 이라고 부르기도 합니다. 딱 한 번만 실행되는 프로세스입니다. 하는 일: airflow db upgrade → DB 스키마 최신화 (DB 구조 최신으로 맞춰줌) 최초 admin 유저 생성 중요 포인트: 이건 계속 도는 서비스가 아닙니다. 할 일 다 하면 바로 종료 (exit code 0). ...

5월 30, 2025

🌱 분갈이 흙 계산기를 만들었어요 – React + Vite + Netlify

✨ 결과물 분갈이 흙 계산기 바로가기 📬 소스코드 GitHub: https://github.com/namikimlab/potting-soil-calculator 🪴 왜 만들었을까? 화분에 식물을 심을 때, 흙이 얼마나 필요한지 계산하는 게 은근히 번거롭습니다. 화분의 모양, 크기, 높이, 개수에 따라 달라지기 때문인데요. 초보 가드너나 원예 입문자들이 직관적으로 흙 용량을 계산할 수 있는 도구가 있었으면 좋겠다는 생각에서 이 프로젝트를 시작했습니다. 🔧 이런 기술을 썼어요 이 계산기는 프론트엔드만으로 구성된 React 웹앱입니다. React + TypeScript: 안정적인 컴포넌트 기반 구조 Vite: 빠른 개발 환경 구성 및 빌드 Tailwind CSS: 가볍고 직관적인 스타일링 Netlify: 정적 사이트 배포 및 HTTPS 자동 적용 Google Analytics (GA4): 방문자 추적 Jest + ts-jest: 100% 유닛 테스트 커버리지 📦 주요 기능 화분 모양 선택 (사각형, 원통형, 원뿔형, 기타) 각 모양에 맞는 사이즈 입력 계산된 결과에 따라 흙 용량(L) 출력 20L + 8L 분갈이흙 제품 조합 추천 마사토(배수용 자갈)도 함께 제안 반응형 웹 지원 (모바일 최적화) SEO를 위한 Open Graph 메타태그, favicon, sitemap.xml, robots.txt 설정 💡 이런 점을 신경 썼습니다 실제 구매로 이어지도록 설계 단순한 계산기 수준이 아니라, 구매 버튼까지 연결되도록 구성했습니다. ...

5월 21, 2025

📊 dbt가 잘하는 일 vs Python이 잘하는 일

역할 dbt가 잘함 Python이 더 낫다 정형 데이터 정제 (staging) ✅ 가능은 하지만 불편함 마트 테이블 구조 설계 ✅ 가능은 함 사용자별로 달라지는 계산 ❌ 불편함 ✅ 매우 유연함 점수화, 조건 매칭, if-else 로직 ❌ 매우 번거로움 ✅ 적합 사용자 입력 기반 필터링 ❌ 불가능 ✅ 핵심 기능 추천 이유 설명, 로직 튜닝 ❌ ✅ 완전 맞춤형 구현 가능 예를 들어 -- dbt에서는 이런 로직이 아주 힘들다... SELECT CASE WHEN user.age BETWEEN policy.min_age AND policy.max_age THEN 30 ELSE 0 END + CASE WHEN user.income < policy.income_ceiling THEN 25 ELSE 0 END + ... dbt에서는 “user”란 존재 자체가 없음 dbt는 “모든 사용자에게 동일하게 적용되는 모델”을 설계하는 도구 반면 Python에서는 사용자가 입력할 때마다 추천 결과가 달라지게 만들 수 있음 👉 dbt는 정적(Static) 모델링에 적합하지만 사용자 입력 기반의 동적(Dynamic) 추천 시스템은 Python이 더 났다. ...

5월 12, 2025

🚀 핀테크 배치 데이터 파이프라인 구축기: AWS, Airflow, Spark

✨ 프로젝트 개요 핀테크 회사를 가정해, 카드사 데이터를 자동으로 집계 → 정제 → 분석하는 배치 파이프라인을 구축해보았다. 실제 데이터를 사용할 수는 없었기에 Faker를 활용해 가상의 거래 데이터를 생성했지만, 전체적인 데이터 흐름과 구조를 설계하는 데에는 충분하다고 생각된다. 🎯 목표 “Airflow를 활용해 현실적인 금융 데이터를 Spark로 처리하고, 저장 및 분석까지 가능한 자동화된 파이프라인을 만들어보자.” 단계 설명 작업 데이터 생성 원시 데이터 준비 Faker로 신용카드 거래 데이터 생성 데이터 수집 저장 위치로 이동 S3에 업로드 (raw) 데이터 처리 정제, 집계 PySpark로 지역별 거래금액 집계 데이터 저장 가공 후 저장 S3에 Parquet 저장 (processed) 데이터 분석 쿼리용 구조 구성 Athena로 테이블 생성 및 SQL 가능 자동화 반복 처리 가능하게 설정 Airflow로 DAG 작성 🔧 기술 스택 오케스트레이션: Apache Airflow 가상 데이터 생성: Python, Faker 데이터 처리: Apache Spark (PySpark) 데이터 저장: AWS S3 데이터 쿼리: AWS Athena 인프라: Docker, Terraform 🧩 아키텍처 구성 가상 데이터 생성 → S3 업로드 → Spark 변환 → S3 저장 → Athena로 쿼리 Python의 Faker 라이브러리로 가상의 신용카드 거래 데이터 CSV 생성 ...

5월 1, 2025

Hugo 포스팅 테스트

안녕하세요 이것은 두꺼운 글씨, 이것은 강조 글씨. Visit the Hugo website!

4월 30, 2025