컨테이너·워크플로우 자동화/DocKer 기본 및 활용

Airflow × Command 기반 컨테이너 실행 구조 이해하기

Data Jun 2026. 2. 24. 14:50

Airflow를 Docker Compose로 구성하면 webserver, scheduler, worker, triggerer가 각각 다른 컨테이너로 실행됩니다. 이때 각 컨테이너는 같은 이미지를 사용하지만, command 값에 따라 역할이 달라집니다.

 

핵심은 다음입니다.
이미지는 동일하지만, 실행 모드가 다르면 전혀 다른 프로세스로 동작합니다.

 

1. 공통 이미지 상속 구조

docker-compose.yml에서는 보통 아래처럼 공통 설정을 정의합니다.

ersion: '3.8'
x-airflow-common:
  &airflow-common
  # In order to add custom dependencies or upgrade provider packages you can use your extended image.
  # Comment the image line, place your Dockerfile in the directory where you placed the docker-compose.yaml
  # and uncomment the "build" line below, Then run `docker-compose build` to build the images.
  image: ${AIRFLOW_IMAGE_NAME:-apache/airflow:2.6.2}
  # build: .
  environment:
    &airflow-common-env
    AIRFLOW__CORE__EXECUTOR: CeleryExecutor
    AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow@postgres/airflow
    # For backward compatibility, with Airflow <2.3
    AIRFLOW__CORE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow@postgres/airflow
    AIRFLOW__CELERY__RESULT_BACKEND: db+postgresql://airflow:airflow@postgres/airflow
    AIRFLOW__CELERY__BROKER_URL: redis://:@redis:6379/0
    AIRFLOW__CORE__FERNET_KEY: ''
    AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION: 'true'
    AIRFLOW__CORE__LOAD_EXAMPLES: 'false'
    AIRFLOW__API__AUTH_BACKENDS: 'airflow.api.auth.backend.basic_auth,airflow.api.auth.backend.session'
    PYTHONPATH: /opt/airflow 
    # yamllint disable rule:line-length
    # Use simple http server on scheduler for health checks
    # See https://airflow.apache.org/docs/apache-airflow/stable/administration-and-deployment/logging-monitoring/check-health.html#scheduler-health-check-server
    # yamllint enable rule:line-length
    AIRFLOW__SCHEDULER__ENABLE_HEALTH_CHECK: 'true'
    # WARNING: Use _PIP_ADDITIONAL_REQUIREMENTS option ONLY for a quick checks
    # for other purpose (development, test and especially production usage) build/extend Airflow image.
    _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-}
    
    
  volumes:
    - ${AIRFLOW_PROJ_DIR:-.}/dags:/opt/airflow/dags
    - ${AIRFLOW_PROJ_DIR:-.}/logs:/opt/airflow/logs
    - ${AIRFLOW_PROJ_DIR:-.}/config:/opt/airflow/config
    - ${AIRFLOW_PROJ_DIR:-.}/plugins:/opt/airflow/plugins
    - ${AIRFLOW_PROJ_DIR:-.}/../src:/opt/airflow/src
    - ${AIRFLOW_PROJ_DIR:-.}/../data:/opt/airflow/data

  user: "${AIRFLOW_UID:-50000}:0"
  depends_on:
    &airflow-common-depends-on
    redis:
      condition: service_healthy
    postgres:
      condition: service_healthy.

그리고 각 서비스에서 이를 상속합니다.

airflow-worker:
  <<: *airflow-common
  command: celery worker

<<: *airflow-common은 공통 이미지와 환경 설정을 그대로 가져오는 YAML 문법입니다.

 

2. command가 역할을 결정한다

예를 들어:

airflow-webserver:
  command: webserver

airflow-scheduler:
  command: scheduler

airflow-worker:
  command: celery worker

모두 같은 Airflow 이미지이지만, 실행 명령이 다릅니다.

 

이는 내부적으로 다음과 같습니다.

airflow webserver
airflow scheduler
airflow celery worker

즉, 같은 실행 파일을 서로 다른 모드로 호출하는 구조입니다.

 

3. 왜 이렇게 분리할까?

Airflow는 역할 기반 프로세스 구조를 가집니다.

  • webserver → UI 제공
  • scheduler → DAG 스케줄 관리
  • worker → 실제 Task 실행
  • triggerer → 비동기 작업 처리

각 역할은 독립적으로 동작해야 하므로, 컨테이너도 분리됩니다.

 

4. 실행 구조 요약

  • 이미지 = 실행 환경
  • command = 역할 정의
  • 컨테이너 = 역할별 실행 인스턴스

같은 이미지를 공유하면서 command로 역할만 나누는 것이 Airflow Docker 구성의 핵심입니다.

Airflow Docker 구성에서는 동일한 이미지를 사용하고, command를 통해 각 컨테이너의 역할을 분리합니다!