요약

  • 인프라 환경 구축: 먼저 안정적인 서버 운용을 위해 고정 IP를 확보하고 VCN 보안 목록에서 SSH(22), Airflow(8080), DB(5432) 포트를 개방하여 네트워크 기초를 마련합니다.
  • 소프트웨어 및 서비스 구축: 서버의 타임존을 한국 표준시(KST)로 변경한 후, PostgreSQL은 호스트 서버에 직접 설치하고 Airflow는 Docker 컨테이너로 구동합니다.
  • 연동 및 최적화: Docker 컨테이너(Airflow)가 호스트(PostgreSQL)에 효율적으로 접속할 수 있도록 docker-compose.yamlextra_hosts 설정을 추가합니다.

0. 들어가며

이전 포스팅에서 Oracle 을 통해 나만의 서버를 구축하였다.

이제 하드웨어(서버)가 준비되었으니 소프트웨어를 올릴 차례입니다. 우리의 목표 아키텍처는 다음과 같다.

  • PostgreSQL: 서버(Host)에 직접 설치 (데이터 영속성 및 관리 용이성)
  • Airflow: Docker 컨테이너로 구동 (설치 복잡도 제거 및 환경 격리)

1. 서버 기초 설정 (타임존 변경)

sudo apt update && sudo apt upgrade -y
sudo timedatectl set-timezone Asia/Seoul
date  # KST라고 나오면 성공

2. PostgreSQL 설치 (Host Install)

2.1 설치 및 설정

sudo apt install postgresql postgresql-contrib -y
sudo systemctl enable postgresql
sudo systemctl start postgresql

2.2 외부 접속 허용

1) postgresql.conf 수정

sudo nano /etc/postgresql/16/main/postgresql.conf
  • listen_addresses = 'localhost'listen_addresses = '*' 로 변경

2) pg_hba.conf 수정

sudo nano /etc/postgresql/16/main/pg_hba.conf

파일 맨 아래에 추가:

host    all             all             0.0.0.0/0               scram-sha-256
sudo systemctl restart postgresql

2.3 DB 및 유저 생성

sudo -i -u postgres
psql
CREATE USER myuser WITH PASSWORD 'mypassword123';
CREATE DATABASE airflow_db;
CREATE DATABASE project;
GRANT ALL PRIVILEGES ON DATABASE airflow_db TO myuser;
GRANT ALL PRIVILEGES ON DATABASE project TO myuser;

3. Airflow 설치 (Docker Compose)

3.1 Docker 설치

sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
sudo usermod -aG docker $USER
exit

3.2 Airflow 실행 및 설정

cd ~
mkdir airflow && cd airflow
mkdir -p ./dags ./logs ./plugins ./config
nano docker-compose.yaml
version: '3.8'
 
x-airflow-common:
  &airflow-common
  image: apache/airflow:2.10.4
  environment:
    &airflow-common-env
    AIRFLOW__CORE__EXECUTOR: LocalExecutor
    AIRFLOW__CORE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow@postgres/airflow
    AIRFLOW__CORE__LOAD_EXAMPLES: 'false'
  volumes:
    - ./dags:/opt/airflow/dags
    - ./logs:/opt/airflow/logs
    - ./plugins:/opt/airflow/plugins
  user: "${AIRFLOW_UID:-50000}:0"
  depends_on:
    postgres:
      condition: service_healthy
  extra_hosts:
    - "host.docker.internal:host-gateway"
 
services:
  postgres:
    image: postgres:13
    environment:
      POSTGRES_USER: airflow
      POSTGRES_PASSWORD: airflow
      POSTGRES_DB: airflow
    volumes:
      - postgres-db-volume:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "airflow"]
      interval: 5s
      retries: 5
    restart: always
 
  airflow-webserver:
    <<: *airflow-common
    command: webserver
    ports:
      - "8080:8080"
    restart: always
 
  airflow-scheduler:
    <<: *airflow-common
    command: scheduler
    restart: always
 
  airflow-init:
    <<: *airflow-common
    command: version
    environment:
      <<: *airflow-common-env
      _AIRFLOW_DB_UPGRADE: 'true'
      _AIRFLOW_WWW_USER_CREATE: 'true'
      _AIRFLOW_WWW_USER_USERNAME: ${_AIRFLOW_WWW_USER_USERNAME:-airflow}
      _AIRFLOW_WWW_USER_PASSWORD: ${_AIRFLOW_WWW_USER_PASSWORD:-airflow}
    user: "0:0"
 
volumes:
  postgres-db-volume:
echo "AIRFLOW_UID=$(id -u)" > .env
docker compose up airflow-init
docker compose up -d
docker compose ps

4. DB 연결 설정

Airflow 웹 UI(http://고정IP:8080) → Admin -> Connections

항목
Conn TypePostgres
Hosthost.docker.internal
Databaseproject
Login/Password설정한 계정 정보

왜 고정 IP가 아닌 host.docker.internal을 사용하는가?

  • 보안: 트래픽이 외부로 나가지 않아 DB 포트를 전 세계에 열 필요 없음
  • 효율성: 내부 통신으로 네트워크 지연 없이 빠르고 안정적

Reference