SSD Nodes Learn Hosting plans →
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-28

Docker Compose 여러 파일 병합 및 설정 가이드

Docker Compose에서 compose.override.yaml이 자동으로 로드되는 원리와 파일 병합 순서를 설명합니다. 포트 충돌 문제와 개발 및 운영 환경 분리를 위한 include 활용법 등 실무에서 흔히 발생하는 설정 오류를 해결하는 방법을 상세히 다룹니다.

Docker Compose가 여러 파일을 처리하는 방식

Docker Compose는 여러 파일을 사용하여 하나의 프로젝트를 빌드할 수 있습니다. Compose는 파일을 전달받은 순서대로 읽어 하나의 모델로 병합하며, 값이 충돌할 경우 나중에 읽은 파일의 값이 우선합니다. 이를 수행하는 메커니즘은 명령줄에서 두 가지가 있습니다. Compose가 자체적으로 로드하는 오버라이드 파일과 사용자가 직접 전달하는 -f 플래그입니다. 세 번째 메커니즘은 파일 내부에 존재하는 include 요소이며, 이는 앞선 두 방식과는 다르게 동작합니다.

병합은 단순한 덮어쓰기가 아닙니다. 매핑은 키 단위로 병합되고, 시퀀스는 추가되며, 일부 필드는 전체가 교체됩니다. 이러한 차이 때문에 예상치 못한 결과가 발생하며, 특히 ports 목록은 거의 모든 사용자가 실수하는 부분입니다.

아래의 모든 내용은 구형 docker-compose 스크립트가 아닌 docker compose 플러그인 형태의 Compose v2를 기준으로 합니다. docker compose version를 실행하여 버전을 확인하십시오. 아직 Compose 파일을 작성하지 않았다면 Docker Compose 기초 가이드를 먼저 읽고 돌아오십시오.

Compose가 자동으로 불러오는 오버라이드 파일

docker compose up 명령을 -f 플래그 없이 실행하면, Compose는 작업 디렉터리와 그 상위 디렉터리에서 compose.yaml 또는 docker-compose.yaml 파일을 찾습니다. 기본 파일 옆에 오버라이드 파일이 있으면 Compose는 이를 자동으로 두 번째 파일로 불러옵니다.

ls compose.yaml compose.override.yaml
docker compose up -d

두 파일이 모두 존재하면, 명령어를 직접 입력하는 것과 동일하게 동작합니다.

docker compose -f compose.yaml -f compose.override.yaml up -d

Compose가 인식하는 파일 이름은 compose.override.yaml, compose.override.yml, 그리고 이전 버전에서 사용하던 docker-compose.override.ymldocker-compose.override.yaml입니다. compose.dev.yaml과 같은 다른 이름의 파일은 -f를 사용하여 명시적으로 지정할 때만 불러옵니다.

-f을 하나라도 전달하는 순간, 자동 불러오기 기능은 중단됩니다. docker compose -f compose.yaml up는 지정된 파일 하나만 읽고 오버라이드 파일을 무시합니다. 이 가이드 뒷부분에서 다룰 개발 및 운영 환경 패턴은 바로 이 특성을 기반으로 합니다.

서버에서는 이 원칙이 양면으로 작용한다. 배포 디렉터리에 남겨 둔 override 파일은 해당 디렉터리에서 실행하는 모든 bare docker compose 명령에 로드되며, cron 작업이 실행하는 명령도 포함된다. 이로 인해 아무도 배포하려 하지 않았던 소스 디렉터리가 production 스택에 bind mount될 수 있다. 배포가 끝날 때마다 docker compose config을 실행하고 출력 결과를 확인한다. 배포가 unattended 방식으로 실행된다면, 문제가 발생했다는 사실을 알려 주는 수단이 있어야 이 검사가 효과가 있다. cron 작업이나 systemd OnFailure unit이 메시지를 게시할 수 있는 self-hosted ntfy 서버 같은 push channel이 그 역할을 한다.

-f 옵션을 사용한 순서 지정 및 상대 경로 해석 방식

Compose는 제공된 파일 순서대로 설정을 구성하며, 뒤에 오는 파일은 앞선 파일의 설정을 덮어쓰거나 추가합니다. 왼쪽에서 오른쪽으로 처리하며, 마지막 파일이 우선합니다.

docker compose -f compose.yaml -f compose.prod.yaml config
docker compose -f compose.yaml -f compose.prod.yaml up -d

해당 프로젝트의 모든 명령은 동일한 파일 목록을 필요로 합니다. up을 두 개의 파일로 실행하고 logs을 한 개의 파일로 실행하면 서로 다른 병합 모델을 참조하게 되며, 이는 Compose가 존재하지 않는다고 보고하는 서비스를 빠르게 만드는 원인이 됩니다. 업그레이드가 일회성 명령으로 실행되는 스택의 경우 위험은 더 커집니다. 예를 들어 자체 호스팅 Chatwoot 지원 데스크의 데이터베이스 마이그레이션 단계에서 잘못된 파일 목록으로 docker compose run를 실행하면, 현재 서비스가 사용 중인 모델이 아닌 다른 모델을 대상으로 작업하게 됩니다. 대신 COMPOSE_FILE 환경 변수를 사용하여 목록을 한 번만 설정하십시오.

export COMPOSE_FILE=compose.yaml:compose.prod.yaml
docker compose config
docker compose up -d

구분자는 Linux에서 :이며, COMPOSE_PATH_SEPARATOR를 통해 변경할 수 있습니다. COMPOSE_FILE은 프로젝트의 .env 파일에 포함될 수도 있으며, 이를 통해 셸 기록이 아닌 체크아웃의 일부로 관리할 수 있습니다. 명령줄에서 명시적으로 설정한 값이 환경 변수보다 우선합니다.

이제 바인드 마운트(bind mount)를 깨뜨리는 규칙에 대해 설명합니다. -f와 함께 여러 파일을 사용할 때, 모든 파일 내의 상대 경로는 해당 경로를 포함하는 파일이 아닌 첫 번째 파일의 디렉터리를 기준으로 해석됩니다. deploy/prod/compose.prod.yaml 내부에 ./data:/var/lib/postgresql/data을 작성하더라도 Compose는 여전히 기본 파일 옆에서 ./data을 찾습니다. Docker는 해당 잘못된 경로에 빈 디렉터리를 생성하고 컨테이너는 아무것도 없는 상태로 시작되는데, 이는 데이터 손실처럼 보이지만 실제로는 그렇지 않습니다. --project-directory를 전달하여 기본 경로를 직접 설정하거나, 각 파일을 해당 파일의 디렉터리를 기준으로 해석하는 include을 사용하십시오.

프로젝트 이름은 동일한 기본 디렉터리에서 결정되므로, 첫 번째 파일을 변경하면 프로젝트 이름이 바뀔 수 있습니다. 프로젝트 이름이 바뀌면 컨테이너 이름과 볼륨 이름이 새로 생성되며, 기존 볼륨은 이전 이름으로 디스크에 그대로 남게 됩니다. 대신 기본 파일의 최상위 수준에 name:을 설정하여 이름을 고정하십시오.

name: myapp

어떤 필드가 병합되고 어떤 필드가 대체되는가

Compose는 필드 이름이 아닌 값의 유형에 따라 병합을 수행합니다.

  • 단일 값 필드는 대체됩니다. image, command, entrypointmem_limit는 나중에 정의된 값을 그대로 사용합니다. 오버라이드 설정이 전체 행을 다시 작성하므로 command에 인수를 추가할 수 없습니다.
  • 매핑은 키 단위로 병합됩니다. environment, labels, volumesdevices은 두 파일의 모든 키를 유지하며, 양쪽 모두에 존재하는 키는 나중에 정의된 파일의 값이 우선합니다. environmentlabels의 경우 키는 변수 또는 레이블 이름입니다. volumesdevices의 경우 키는 컨테이너 경로입니다.
  • 시퀀스는 추가됩니다. dns, dns_search, expose, tmpfsexternal_links는 서로 연결됩니다. expose: ["3000"]을 포함하는 기본 파일과 ["4000", "5000"]을 포함하는 오버라이드 파일을 병합하면 ["3000", "4000", "5000"]가 생성됩니다.

네 가지 시퀀스는 식별 키를 가지므로, 해당 키가 일치하는 항목은 추가되지 않고 병합됩니다. volumes, secretsconfigstarget을 기준으로 일치 여부를 판단합니다. portsip, target, publishedprotocol의 조합을 기준으로 일치 여부를 판단합니다.

ports 규칙을 두 번 읽어 보십시오. 이것이 함정이 될 수 있기 때문입니다. 두 포트 항목은 네 가지 요소가 모두 일치할 때만 동일한 항목으로 간주됩니다. 이 중 하나라도 변경하면 Compose는 이를 서로 관련 없는 두 번째 포트로 인식하여 둘 다 유지합니다.

오버라이드 후에도 포트가 계속 공개되는 이유

모든 인터페이스에서 서비스를 공개하는 기본 파일입니다:

services:
  web:
    image: nginx:1.27
    ports:
      - "8080:80"

리버스 프록시를 앞에 두기 위해 localhost로만 바인딩하도록 작성한 오버라이드입니다:

services:
  web:
    ports:
      - "127.0.0.1:8080:80"

작동한다고 가정하기 전에 결과를 확인하십시오.

docker compose -f compose.yaml -f compose.prod.yaml config

출력에 두 항목이 모두 포함되어 있습니다. ip 부분이 0.0.0.0127.0.0.1로 서로 다르기 때문에, 병합 과정에서는 이를 서로 다른 두 포트로 간주하며 제거하려던 공개 바인딩이 모델에 그대로 남아 있게 됩니다. 이는 다른 환경보다 Docker에서 더 중요한데, 공개된 포트는 방화벽 규칙보다 앞서 iptables에 기록되기 때문입니다. 이 메커니즘은 Docker 공개 포트가 ufw를 우회하는 이유에서 다룹니다.

두 가지 해결 방법이 있습니다. 명시적인 방법은 !override 태그를 사용하는 것으로, 이는 전체 속성을 대체하여 병합 규칙을 건너뜁니다:

services:
  web:
    ports: !override
      - "127.0.0.1:8080:80"

!override은 Compose v2.24.4 이상이 필요합니다. 이식 가능한 해결책은 태그를 전혀 사용하지 않는 것입니다. 기본 파일에서 ports을 완전히 제외하고 환경별 파일에서만 선언하십시오. 병합할 대상이 없으면 정보가 유출될 일도 없습니다. 이것이 아래의 실습 예제에서 사용된 패턴입니다.

기본 파일 세트에서 값 삭제하기

!reset는 속성을 제거하여 기본값이나 null로 되돌립니다. 이 명령은 값을 인자로 받지만 해당 값은 무시하므로, 유효하면서도 비어 있는 값을 작성하십시오.

services:
  web:
    ports: !reset []
    environment:
      DEBUG: !reset null

!reset는 Compose v2.24 이상 버전이 필요합니다. 기본 파일을 직접 수정할 수 없는 경우, 예를 들어 외부에서 가져온 벤더 조각(fragment)을 다룰 때 이 기능을 사용하십시오. 배포된 업스트림 스택이 바로 그런 경우입니다. 자체 호스팅 AFFiNE 워크스페이스의 Compose 파일은 사용자가 작성하지 않은 4개의 컨테이너를 선언합니다. 이때 !reset을 사용하면 파일을 포크하거나 변경 사항을 계속 추적해야 하는 부담 없이 특정 컨테이너의 속성 하나를 지울 수 있습니다.

include, 부품으로 구성된 스택을 위한 포함 기능

include는 다른 Compose 애플리케이션을 현재 모델로 불러옵니다. 이는 플래그가 아닌 최상위 요소입니다.

include:
  - path: ../commons/compose.yaml

include에 지정된 각 경로는 고유한 프로젝트 디렉터리를 가진 별도의 Compose 애플리케이션 모델로 로드됩니다. 따라서 해당 파일 내부의 상대 경로는 파일 자신의 디렉터리를 기준으로 해석됩니다. 이것이 -f와의 실질적인 차이점이며, 조각이 다른 폴더나 다른 저장소에 있을 때 include를 사용해야 하는 이유입니다. 이는 직접 작성하지 않은 벤더 스택의 일반적인 형태입니다. 예를 들어 자체 호스팅 Authentik SSO 설치를 위한 다중 서비스 Compose 파일은 고유한 상대 경로를 유지한 채 별도의 디렉터리에 둘 수 있으며, 사용자의 파일은 사용자의 서비스에만 집중할 수 있습니다.

긴 형식은 하위 옵션을 지원합니다.

include:
  - path:
      - ../monitoring/compose.yaml
      - ../monitoring/compose.vps.yaml
    project_directory: ../monitoring
    env_file: ../monitoring/.env

path은 리스트를 허용하며, 해당 파일들은 일반적인 규칙에 따라 병합된 후 결과가 모델에 결합됩니다. project_directory은 포함된 파일 내의 상대 경로를 해석하는 데 사용되는 기본 경로를 설정합니다. env_file은 포함된 파일에 보간을 위한 고유 변수를 제공하며, 이를 통해 공유 조각이 프로젝트의 .env를 의도치 않게 읽는 것을 방지합니다. include은 Compose v2.20.0 이상이 필요합니다. 동일한 옵션은 이미 실행 중인 스택에 단일 컨테이너 애드온을 추가할 때도 적합합니다. 예를 들어 Jellyfin 라이브러리를 90년대 비디오 대여점처럼 꾸며주는 Halcyon의 경우, 해당 파일은 고유한 이미지 태그와 env_file을 유지하므로 업데이트 시 미디어 스택이 포함된 파일을 수정할 필요가 없습니다.

사용자의 파일과 포함된 파일 간에 리소스 이름이 중복되면 조용히 병합되지 않고 오류로 보고됩니다. 이는 의도된 동작입니다. 포함된 파일에 선언된 내용을 변경하려면 compose.override.yaml에 변경 사항을 넣어야 합니다. 오버라이드는 조립된 모델에 적용되므로, 포함된 리소스와 충돌하지 않으면서 해당 리소스를 수정할 수 있습니다. 이러한 습관은 PhotoPrism과 Immich 비교에서 다룬 다중 컨테이너 사진 서버처럼 릴리스마다 업스트림 파일이 덮어쓰여지는 스택에서 가장 효과적입니다. localhost 바인딩이나 추가 볼륨과 같은 설정은 다음 업그레이드 시 교체될 파일이 아닌, 사용자의 오버라이드 파일에 두어야 합니다.

요약하자면, include은 별도의 애플리케이션을 구성하고, -f는 하나의 애플리케이션에 설정을 계층화합니다.

단일 VPS에서의 개발 및 운영 환경 분리

세 개의 파일로 구성된 전체 패턴은 다음과 같습니다. 기본 파일은 모든 환경에서 공통으로 적용되는 설정을 선언하며, 어떤 포트도 외부에 노출하지 않습니다.

name: myapp

services:
  app:
    image: ghcr.io/example/app:1.4.2
    environment:
      DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@db:5432/app
      LOG_LEVEL: info
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_DB: app
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  db_data:

depends_on 조건은 애플리케이션이 단순히 컨테이너가 존재하는 상태가 아니라, 응답 가능한 데이터베이스를 기다리게 합니다. 자세한 내용은 healthchecks 및 depends_on 조건을 참조하십시오. POSTGRES_PASSWORD은 프로젝트의 .env 파일에서 가져오며, 이 파일은 git에 포함해서는 안 됩니다. 더 안전한 방법은 env 파일 및 Compose secrets를 참조하십시오.

다음은 Compose가 자동으로 불러오는 compose.override.yaml 파일입니다. 이는 개발자용 파일입니다.

services:
  app:
    build: .
    command: npm run dev
    environment:
      LOG_LEVEL: debug
    ports:
      - "3000:3000"
    volumes:
      - ./src:/app/src

  db:
    ports:
      - "127.0.0.1:5432:5432"

노트북 환경에서는 별도의 옵션 없이 docker compose up를 실행하면 두 파일이 병합됩니다. command은 단일 값을 가지므로 이미지 기본값을 대체합니다. LOG_LEVELenvironment이 키 단위로 병합되기 때문에 info를 대체합니다. 바인드 마운트와 두 개의 노출된 포트는 순수하게 추가되는 설정이며, 데이터베이스 포트는 localhost에만 바인딩되어 공유 네트워크상의 다른 기기에 PostgreSQL이 노출되지 않습니다.

마지막으로 compose.prod.yaml 파일입니다. 이 파일의 이름은 Compose가 자동으로 찾는 이름이 아니므로 실수로 로드될 일이 없습니다.

services:
  app:
    ports:
      - "127.0.0.1:8000:3000"
    deploy:
      resources:
        limits:
          memory: 512M

VPS에서는 두 파일을 모두 지정해야 하며, 파일을 명시적으로 지정하는 것만으로도 오버라이드 파일이 제외됩니다.

docker compose -f compose.yaml -f compose.prod.yaml config
docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose -f compose.yaml -f compose.prod.yaml ps

ps를 실행하면 두 서비스가 모두 실행 중으로 표시되어야 하며, db(healthy)을 보여줍니다. -f을 전달했기 때문에 compose.override.yaml는 읽히지 않았습니다. 따라서 개발용 명령어, 소스 바인드 마운트, 공개 포트 3000은 같은 디렉터리에 파일이 존재하더라도 운영 환경에 영향을 줄 수 없습니다. 포트 8000은 localhost에만 열려 있어 프록시를 사용할 준비가 된 상태입니다. 두 번째 서비스를 추가할 때는 Traefik 뒤에서 여러 앱 실행하기를 참조하십시오.

서버의 .envCOMPOSE_FILE=compose.yaml:compose.prod.yaml을 설정하면 이후 명령어는 다시 일반적인 docker compose logs -f app만 사용해도 됩니다.

단일 서비스 스택도 동일한 구조를 가집니다. 자체 호스팅 openGym 운동 추적기는 첫 번째 패스키를 등록하기 전에 프록시 뒤에서 TLS를 통해 응답해야 하기 때문입니다. ports이 없는 기본 파일을 사용하면 의도치 않은 포트 바인딩이 프록시보다 먼저 요청을 가로채는 일을 방지할 수 있습니다.

배포 전 병합된 모델 확인하기

docker compose config는 완전히 병합되고 보간된 모델을 출력합니다. 이는 미리보기가 아닙니다. Compose가 실제로 처리할 입력값이므로, 출력 결과가 예상과 다르다면 출력된 내용이 정확한 것입니다.

docker compose -f compose.yaml -f compose.prod.yaml config
docker compose -f compose.yaml -f compose.prod.yaml config --no-interpolate
docker compose -f compose.yaml -f compose.prod.yaml config --services

--no-interpolate${VAR}을 확장하지 않은 상태로 유지합니다. 일반 config은 모든 해석된 비밀 값을 평문으로 출력하므로, 출력을 다른 곳에 붙여넣기 전에 이 옵션을 사용하십시오. --services은 서비스 이름만 나열하며, 이는 include가 예상대로 정보를 가져왔는지 빠르게 확인하는 방법입니다.

실패 유형 및 확인 방법

no configuration file provided: not found. Compose가 읽을 파일을 찾지 못했습니다. 프로젝트 디렉터리 외부에서 실행 중이거나, COMPOSE_FILE에 지정한 경로가 존재하지 않는 경우입니다. Compose는 기본 베이스 파일을 찾기 위해 상위 디렉터리를 탐색하지만, 사용자가 직접 지정한 파일은 별도로 탐색하지 않습니다.

WARN[0000] The "POSTGRES_PASSWORD" variable is not set. Defaulting to a blank string. 보간(interpolation)은 프로젝트의 .env 파일과 셸 환경 변수를 기준으로 처리되며, 여기서 프로젝트 디렉터리는 첫 번째 -f 파일이 위치한 디렉터리입니다. .env가 포함된 디렉터리가 아닌 다른 곳에서 배포를 시도하면 이 경고가 발생하며, 이후 데이터베이스가 모든 연결을 거부하게 됩니다.

오버라이드 수정 사항이 docker compose config에 반영되지 않습니다. 자동 오버라이드 로딩을 비활성화하는 -f 옵션을 사용했거나, Compose가 상위 디렉터리에서 compose.yaml 파일을 찾아 사용자의 오버라이드 파일이 무시된 경우입니다. 다른 인자 없이 docker compose config를 실행하면 Compose가 실제로 어떤 모델을 빌드하고 있는지 확인할 수 있습니다.

바인드 마운트가 비어 있고 Docker가 의도하지 않은 디렉터리를 생성했습니다. 상대 경로가 첫 번째 파일의 디렉터리를 기준으로 해석되었기 때문입니다. 경로를 수정하거나, --project-directory 옵션을 전달하거나, 해당 조각을 include 뒤로 이동하십시오.

컨테이너 이름이 바뀌어 생성되고 볼륨이 비어 있는 것처럼 보입니다. 프로젝트 이름은 첫 번째 파일의 디렉터리를 따르기 때문에 디렉터리가 바뀌면 프로젝트 이름도 변경됩니다. 베이스 파일 최상위에 name:를 추가하면 이름이 고정됩니다. 이전 볼륨은 여전히 이전 접두사 아래에 남아 있으며, docker volume ls 명령으로 확인할 수 있습니다.

오버라이드에서 제거한 포트가 여전히 열려 있습니다. ports 병합 방식은 설정을 대체하는 것이 아니라 추가하는 방식이기 때문입니다. docker compose config로 설정을 확인한 뒤, !override을 사용하거나 ports을 베이스 파일에서 제거하십시오.

FAQ

Compose는 자동으로 compose.override.yaml을 불러옵니까?

네, docker compose-f 플래그 없이 실행하면 자동으로 불러옵니다. Compose는 작업 디렉터리와 상위 디렉터리에서 compose.yaml 또는 docker-compose.yaml을 찾으며, 같은 위치에 오버라이드 파일이 있으면 해당 파일을 두 번째로 불러옵니다. 인식되는 파일명은 compose.override.yaml, compose.override.yml, docker-compose.override.yml, docker-compose.override.yaml입니다. -f을 전달하면 이 기능이 비활성화되므로, docker compose -f compose.yaml up은 지정된 파일 하나만 읽습니다.

여러 -f 파일을 병합하는 순서는 어떻게 됩니까?

왼쪽에서 오른쪽 순서입니다. Compose는 제공한 순서대로 설정을 구성하며, 각 파일은 이전 파일의 설정을 덮어쓰거나 추가합니다. 따라서 명령줄에서 마지막에 위치한 파일의 설정이 충돌 시 우선권을 갖습니다. 해당 프로젝트의 모든 명령에 동일한 목록을 사용해야 하며, 이를 위해 COMPOSE_FILE=compose.yaml:compose.prod.yaml을 사용합니다.

오버라이드했는데도 포트가 여전히 게시되는 이유는 무엇입니까?

ports 항목은 ip, target, published, protocol 전체 세트로 식별되기 때문입니다. 기본 파일의 8080:80에 대해 127.0.0.1:8080:80로 오버라이드하면 ip 부분이 다르므로, Compose는 이를 두 번째 포트로 간주하여 둘 다 유지합니다. docker compose config을 실행하면 두 항목을 모두 확인할 수 있습니다. Compose v2.24.4 이상에서는 ports: !override을 사용하거나, 병합할 대상이 없도록 기본 파일에서 ports를 제거하십시오.

include와 -f의 차이점은 무엇입니까?

-f은 여러 파일을 하나의 애플리케이션에 계층화하며, 모든 파일 내의 상대 경로는 첫 번째 파일의 디렉터리를 기준으로 해석됩니다. include은 별도의 Compose 애플리케이션을 불러오며, 포함된 각 경로는 고유한 프로젝트 디렉터리를 유지하므로 상대 경로도 해당 디렉터리를 기준으로 해석됩니다. 자신의 스택에 대한 환경 계층화에는 -f를 사용하고, 외부에서 관리되는 조각을 가져올 때는 include을 사용하십시오. include는 Compose v2.20.0 이상이 필요합니다.

기본 파일에 설정된 값을 제거하려면 어떻게 해야 합니까?

Compose v2.24 이상에서는 !reset 태그를 사용하십시오. 오버라이드 파일에 ports: !reset [] 또는 MY_VAR: !reset null을 작성하면 해당 속성이 기본값이나 null로 돌아갑니다. 태그에 지정하는 값은 필수이지만 무시됩니다. 속성을 지우는 대신 교체하려면 !override을 사용하며, 이는 v2.24.4 이상이 필요합니다.