Docker Compose를 통해 Airflow 환경을 구축하다 보면 반드시 보게 되는 파일이 있습니다. 바로 .yaml 파일입니다. 프로젝트의 핵심 설정이 담기는 yaml 파일은 현대 개발 생태계에서 빼놓을 수 없는 요소입니다.

 

저도 부트캠프 최종 프로젝트에서 Airflow를 구축하며 처음으로 docker-compose.yaml 파일을 마주했습니다. 가이드에 따라 파일을 설치하고 실행하니 마법처럼 Airflow가 구동되었습니다. 하지만 문득 궁금해졌습니다. 이 파일 안에 가득한 지시어들은 정확히 어떤 의미일까? 왜 하필 .yaml 파일일까? 무심코 지나칠 수 있었던 YAML에 대해 제가 공부한 내용을 정리해 보았습니다. 

 

이번 포스팅에서는 프로젝트 경험을 바탕으로 YAML의 정의부터 주요 특징, 그리고 왜 많은 도구들이 YAML을 설정 파일 형식으로 채택하는지를 심도 있게 다뤄보고자 합니다.

airflow의 docker-compose.yaml 파일 예시

yaml이란

YAML은 원래 'Yet Another Markup Language(또 다른 마크업 언어)'의 약자였지만, 나중에는 'YAML Ain't Markup Language(YAML은 마크업 언어가 아니다)'라는 뜻으로 이름이 바뀌었습니다.

이걸 꼭 알아야 하냐고요? 아뇨. 하지만 전 꼭 말해드리고 싶었습니다. 어쨌든, YAML은 Docker Compose나 Kubernetes 같은 많은 유명한 도구들의 설정을 구성하는 데 사용됩니다.

그리고 괄호나 태그(acorn)를 사용해 형식을 맞추는 JSON, XML과는 달리, YAML은 '공백 들여쓰기'를 사용합니다.

# yaml(공백 중심)
user:
  name: "dong-ho"
  role: "ML engineer"
  skills:
    - Python
    - Docker
    
# json(괄호 중심)
{
  "user": {
    "name": "dong-ho",
    "role": "ML engineer",
    "skills": ["Python", "Docker"]
  }
}

# XML(태그 중심)
<user>
  <name>dong-ho</name>
  <role>ML engineer</role>
  <skills>
    <skill>Python</skill>
    <skill>skill>Docker</skill>
  </skills>
</user>

Scalars(data type)

Yaml에서 scalars는 단일 값을 나타내는 기본 단위이며, Yaml은 데이터 타입을 명시하지 않아도 알아서 판단하는 똑똑한 능력이 있습니다. Sclars의 종류는 총 5가지가 있습니다.

  1. 문자열(string): 텍스트 데이터. 따옴표 없이 표현 가능하며, 특수문자나 공백이 포함되면 따옴표 사용
  2. 숫자 (Number): 정수와 부동소수점. 8진수(0o), 16진수(0x), 지수 표기법 지원
  3. 불린 (Boolean): true/false, yes/no, on/off 등 여러 표현 가능
  4. Null: 값이 없음을 나타냄. null, ~, 빈 값으로 표현
  5. 날짜/시간: ISO 8601 형식 지원
# Integer
positive: 34
zero: 0
negative: -12
hex: 0xDEADBEEF

# Boolean
# recommended boolean usage
is_gold: true
is_released: false
# legacy boolean usage(avoid)
is_gold: on
is_released: off

# Date
# YYYY-MM-DD
created: 2027-02-11
# YYYY-MM-DD HH:mm:ss
created: 2027-02-11 11:02:56

# Float
positive: 3.14
negative: -8.6
infinity: .inf
not-a-number: .nan

 

문자열(strings) 표현법

YAML 스칼라 중 가장 강력하고 복잡한 것이 문자열입니다. 따옴표를 쓰느냐 안 쓰느냐에 따라 의미가 달라집니다.

방식 예시 특징
Plain (따옴표 없음) name: Gemini 가장 간결함. 특수문자가 포함되면 오류 가능성 있음.
Single Quotes ('' ) 'Hello \n World'   있는 그대로 인식. \n을 줄바꿈으로 해석하지 않음.
Double Quotes (" ") "Hello \n World" 이스케이프 시퀀스 해석. \n을 실제 줄바꿈으로 인식함.

여러 줄 스칼라

Docker Compose나 Airflow 설정을 하다 보면 긴 스크립트를 써야 할 때가 있습니다. 이때 사용하는 두 가지 기호가 핵심입니다.

 

1. 리터럴 스타일 (|): 줄바꿈을 포함하여 작성한 모양 그대로를 저장합니다.

description: |
  첫 번째 줄입니다.
  두 번째 줄입니다.
  (줄바꿈이 유지됩니다.)

2. 폴디드 스타일 (>): 작성할 때는 여러 줄이지만, 실제 데이터로 읽을 때는 중간의 줄바꿈을 공백 하나로 바꿉니다. (문단 끝의 줄바꿈만 유지)

summary: >
  이 내용은 여러 줄로
  작성되었지만 실제로는
  한 줄의 문장으로 읽힙니다.

Mapping(object)

YAML에서 데이터를 구조화하는 가장 기본적인 단위는 매핑(Mapping)입니다. 우리가 흔히 프로그래밍에서 말하는 '객체'와 같은 개념입니다. 재미있는 점은 YAML이 '공백'에 매우 민감하다는 것입니다. 단순히 글자를 적는 게 아니라, 콜론 뒤에 한 칸을 띄우고 아래 줄에서 들여쓰기를 하는 그 '빈 공간'이 데이터 간의 부모-자식 관계를 결정합니다.

Airflow 설정 파일에서 services: 아래에 airflow-webserver: 같은 항목이 들어가는 것도 바로 매핑 원리를 이용한 것입니다.

# Yaml
info:
    lang: python
    version: 3.14.1
    type: open-source

# json
{
    "info": {
    	"lang": "python"
        "version": "3.14.1"
        "type": "open-source"
    }
}

Sequence(List)

Yaml에서 배열을 생성하기 위해서는 dash나 공백을 사용합니다. 배열은 파이썬에서 사용하는 그것과 같은 개념으로 순서가 존재합니다.

 

1. 블록 스타일: 가장 일반적입니다. dash 뒤에 반드시 공백이 있어야 합니다. 공백을 사용하지 않으면 문자열로 인식됩니다.

# block style
language:
    - python
    - java
    - go

2. 괄호 스타일: json과 유사하게 괄호를 사용하는 방식입니다.

# flow style
language: [python, java, go]

 

Sequence와 Mapping의 조합

실제 docker compose나 airflow 설정에서는 '객체들을 담은 리스트' 형태를 가장 많이 마주합니다.

employee
    - name: jnb
      role: designer
    - name: kxn
      role: pm

 

employee라는 객체 안에 두 개의 sequence가 들어가 있는 형태입니다. 각 dash는 새로운 시작점입니다. 이때도 마찬가지로 dash 후에 꼭 공백을 작성해야 합니다!

docker-compose.yaml 파일 분석

version: '3.8'  # [스칼라] 키-값 쌍의 버전 정보

services:        # [매핑] 서비스들을 담는 최상위 객체
  airflow-webserver:  # [매핑] 웹서버 서비스 정의
    image: apache/airflow:2.7.1  # [스칼라] 이미지 이름
    restart: always              # [스칼라] 재시작 정책
    
    volumes:      # [리스트] 여러 경로를 연결하기 위한 목록
      - ./dags:/opt/airflow/dags      # [리스트 항목 1]
      - ./logs:/opt/airflow/logs      # [리스트 항목 2]
      - ./plugins:/opt/airflow/plugins # [리스트 항목 3]

    environment:  # [매핑] 환경 변수 설정 객체
      _PIP_ADDITIONAL_DEPENDENCIES: "pandas numpy" # [스칼라]
  • 구조적 계층: services라는 큰 바구니(매핑) 안에 airflow-webserver라는 작은 바구니가 있고, 그 안에 다시 이미지 이름(스칼라)과 볼륨 목록(리스트)이 담겨 있습니다.
  • 들여쓰기의 마법: 별도의 괄호가 없어도 들여쓰기만으로 volumes가 airflow-webserver에 속한 설정이라는 것을 명확히 알 수 있습니다.

Airflow가 yaml 파일을 사용하는 이유

Airflow에서 docker compose를 위해서 yaml을 사용하는 이유는 명확한 기술적 이점이 있기 때문입니다.

 

① 개발자를 배려하는 '가독성'

Docker Compose나 Airflow의 설정은 인프라 구조를 정의합니다. JSON처럼 { }와 ,가 가득하면 눈이 피로하고 구조를 한눈에 파악하기 어렵지만, YAML은 문서처럼 읽히기 때문에 복잡한 컨테이너 간의 관계를 파악하는 데 최적입니다.

 

② 주석(#)의 존재 (가장 큰 이유 중 하나)

JSON은 공식적으로 주석을 지원하지 않습니다. 하지만 인프라 설정 파일에는 "이 포트를 왜 열었는지", "이 볼륨은 왜 연결했는지" 기록하는 것이 필수적입니다. YAML은 #을 통해 상세한 설명을 남길 수 있어 협업과 유지보수에 유리합니다.

 

③ 유연한 데이터 표현

Airflow는 DAG(작업 흐름)를 정의할 때 환경 변수나 의존성을 복잡하게 설정해야 합니다. YAML은 문자열을 여러 줄로 쓰거나(|), 복잡한 리스트 안에 객체를 넣는 작업을 기호의 방해 없이 깔끔하게 처리할 수 있게 해줍니다.

 

④ 인프라 업계의 표준 (Infrastructure as Code)

Kubernetes, Docker 등 현대 인프라 도구들은 모두 YAML을 기본으로 채택하고 있습니다. 따라서 Airflow 환경을 구축할 때 YAML을 사용하는 것은 다른 도구들과의 호환성 및 생태계 통합 면에서 매우 유리한 선택입니다.

 

결국 YAML이 Docker와 Airflow에서 사랑받는 이유는 컴퓨터도 잘 알아듣지만, 사람에게 가장 친절한 언어이기 때문입니다. 부트캠프 프로젝트를 진행하며 무심코 복사했던 그 코드들 속에 들여쓰기와 콜론 하나하나가 인프라의 뼈대를 구성하는 정교한 설계도였다는 것을 이해하니 설정 파일이 더 이상 어렵게 느껴지지 않았습니다.

+ Recent posts