Docker build 실패 (max depth exceeded)

결론 미리보기

docker build 할 때 max depth exceeded 가 발생한다면 실행중인 컨테이너를 종료하고 관련된 내용을 모두 삭제한 후 다시 빌드하면 정상적으로 빌드가 된다.

 

에러 원인 분석하기

docker compose 를 사용해서 ariflow 를 build 하려다가 에러가 발생했다.

$ docker compose build
[+] Building 0.1s (9/9) FINISHED                                                                                                                                                                                           docker:default
 => [airflow-init internal] load build definition from Dockerfile                                                                                                                                                                    0.0s
 => => transferring dockerfile: 581B                                                                                                                                                                                                 0.0s
 => [airflow-init internal] load metadata for docker.io/apache/airflow:2.10.1                                                                                                                                                        0.0s
 => [airflow-init internal] load .dockerignore                                                                                                                                                                                       0.0s
 => => transferring context: 2B                                                                                                                                                                                                      0.0s
 => [airflow-init 1/5] FROM docker.io/apache/airflow:2.10.1                                                                                                                                                                          0.0s
 => [airflow-init internal] load build context                                                                                                                                                                                       0.0s
 => => transferring context: 38B                                                                                                                                                                                                     0.0s
 => CACHED [airflow-init 2/5] RUN apt-cache search openjdk                                                                                                                                                                           0.0s
 => CACHED [airflow-init 3/5] RUN apt-get update && apt-get install -y     gcc     python3-dev     openjdk-17-jdk     procps     && apt-get clean     && rm -rf /var/lib/apt/lists/*                                                 0.0s
 => CACHED [airflow-init 4/5] COPY ./requirements.txt /opt/airflow/requirements.txt                                                                                                                                                  0.0s
 => ERROR [airflow-init 5/5] RUN pip install -r /opt/airflow/requirements.txt                                                                                                                                                        0.0s
------
 > [airflow-init 5/5] RUN pip install -r /opt/airflow/requirements.txt:
------
failed to solve: failed to prepare latyvuuhqcxqrnsj2a9688ueu as gj50lkfrj9wgdoi8y6ad9e1yf: max depth exceeded

 

로그를 살펴보니 Dockerfile 에서 파이썬 라이브러리를 requirements.txt 파일을 통해서 설치하는 과정에서 에러가 발생한 것으로 보였고 그 아래에는 알기 어려운 내용인 최대 depth 를 초과했다는 메시지가 보였다.

 

에러에 대해 살펴보니 max depth exceeded 에러는 Docker 이미지 빌드 과정에서 생성되는 레이어의 최대 개수(약 125개)를 초과했을 때 발생한다고 한다. 음... 왜 초과했을까...

 

GPT 를 통해 해당 에러에 대해서 검색해보니 다음과 같이 설명해주었다.

 

pip install 을 하는 과정에서 BuildKit 이 무언가를 압축 또는 전개하면서 디렉터리 깊이나 심볼릭 링크가 무한 반복되는 상황을 만났을 때 이러한 에러가 발생한다고 한다. 그래서 Dockerfile 에서 에러가 발생하는 것이 아니라 requirements.txt 파일 안에 있는 패키지에 문제가 있을 가능성이 높다고 했다.

 

일단은 정확한 로그를 확인하기 위해서는 다음과 같이 실행하라고 해서 한번 해보았다.

DOCKER_BUILDKIT=0 docker compose build

 

docker 의 buildkit 을 사용하지 않고 빌드하는 것 같은데 정확한 에러 로그가 발생한다고 한다.

 

실행하게 되면 아래와 같이 계속해서 용량이 올라가게 되는데  1GB 가 넘도록 멈추지 않아 종료시켜버렸다.

Sending build context to Docker daemon  60.85MB

 

그래서 다음으로 requirements.txt 파일 안에 어떤 패키지가 문제가 있는지 확인해보았는데 ML 패키지 때문에 문제가 발생할 수 있다고 한다.

 

현재 requirements.txt 파일 안에 ML 관련 패키지로는 이렇게 사용하고 있다.

torch==2.6.0
lightning==2.5.1.post0
pytorch-forecasting==1.3.0
autogluon==1.4.0

 

분명 처음에 설치할 때에는 빌드가 정상적으로 되었고 얼마 전까지도 괜찮았는데 왜 갑자기 이러는걸까....

결국에는 이전에는 정상으로 동작했지만 현재 되지 않는다는 것은 어떤 부분에서 변화가 생겼다고 볼 수 있고

그래서 문제가 발생할 수 있는 부분들에 대해서 생각해보고 여러 가정들을 세워봤는데

 

갑자기 패키지가 변경되어서 설치하는데 문제가 생길 수 있다?

Docker BuildKit 이 업데이트 되어서 문제가 생길 수 있다?

그것도 아니라면...?

 

그래서 이것저것 변경해가면서 어떤 부분에 문제가 있는지 확인해보았다.

 

먼저, 문제가 될 것 같은 패키지를 제외하고 시도해보았지만 여전히 같은 문제가 발생했다.

그래서 더 찾아보니 Airflow 2.10.1 이미지 자체의 pip 구조와 BuildKit 이 충돌해서 발생하는 문제라고 한다.

특히 python 3.12 버전 + pip 24.x 버전 + BuildKit 조합에서 이런 에러가 많이 발생한다고 한다.

 

그래서 일단 pip 와 docker Buildkit 버전을 확인해보았다.

$ python3 -V
Python 3.12.5

$ pip --version
pip 24.2 from /home/airflow/.local/lib/python3.12/site-packages/pip (python 3.12)

 

그리고 airflow docker 이미지도 확인해보았다.

아래와 같이 내가 사용하는 이미지는 1년 전에 배포가 되고 변경된 적이 없는 것으로 보인다.

 

여기까지 확인해봤지만 정확한 이유를 모르겠어서 일단은 설치가 되도록 변경해보려고 했다.

먼저 pip wheel 캐시를 비활성화해보았다.

# 변경 전
RUN pip install -r /opt/airflow/requirements.txt

# 변경 후
RUN pip install --no-cache-dir -r /opt/airflow/requirements.txt

 

그래도 동일한 에러가 발생했다.

 

여기까지 airflow 2.10.1 버전은 업데이트 된 적이 없고 파이썬 패키지에도 문제가 없었다.

그리고 Dockerfile 을 변경해보았지만 그래도 문제가 해결되지는 않았다.

 

그럼 남은 부분은 Docker BuildKit 밖에 없는데 왜 그런걸까?

 

그래서 간단한 Dockerfile 을 만들어서 테스트해보았다.

FROM apache/airflow:2.10.1
RUN echo "hello"

 

그리고 빌드해보았는데 문제 없이 잘된다.

$ docker build -t airflow_test .
[+] Building 0.2s (6/6) FINISHED                                                                                                                                                                                             docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                                                   0.0s
 => => transferring dockerfile: 82B                                                                                                                                                                                                    0.0s
 => [internal] load metadata for docker.io/apache/airflow:2.10.1                                                                                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                                                                        0.0s
 => CACHED [1/2] FROM docker.io/apache/airflow:2.10.1                                                                                                                                                                                  0.0s
 => [2/2] RUN echo "hello"                                                                                                                                                                                                             0.2s
 => exporting to image                                                                                                                                                                                                                 0.0s
 => => exporting layers                                                                                                                                                                                                                0.0s
 => => writing image sha256:4899e407d413babec083e56e2e63323e7ea28789e58896409d460d9c75b0b1cb                                                                                                                                           0.0s
 => => naming to docker.io/library/airflow_test

 

그럼 위의 Dockerfile 에다가 pip 를 추가해보았다.

FROM apache/airflow:2.10.1
RUN pip install requests

 

다시 빌드해봤는데 잘된다....

$ docker build -t airflow_test .
[+] Building 1.5s (6/6) FINISHED                                                                                                                                                                                             docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                                                   0.0s
 => => transferring dockerfile: 90B                                                                                                                                                                                                    0.0s
 => [internal] load metadata for docker.io/apache/airflow:2.10.1                                                                                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                                                                        0.0s
 => CACHED [1/2] FROM docker.io/apache/airflow:2.10.1                                                                                                                                                                                  0.0s
 => [2/2] RUN pip install requests                                                                                                                                                                                                     1.4s
 => exporting to image                                                                                                                                                                                                                 0.0s
 => => exporting layers                                                                                                                                                                                                                0.0s
 => => writing image sha256:45778c8c2a765781a0a91769b469ca78c3587ac99bf98db45b37f986181f4928                                                                                                                                           0.0s
 => => naming to docker.io/library/airflow_test

 

다시 아까 에러가 발생한 부분을 가져와서 추가해보았다.

FROM apache/airflow:2.10.1

USER airflow

COPY ./requirements.txt /opt/airflow/requirements.txt
RUN pip install -r /opt/airflow/requirements.txt

 

빌드가 잘된다........

$ docker build -t airflow_test .
[+] Building 3.6s (8/8) FINISHED                                                                                                                                                                                             docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                                                   0.0s
 => => transferring dockerfile: 184B                                                                                                                                                                                                   0.0s
 => [internal] load metadata for docker.io/apache/airflow:2.10.1                                                                                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                                                                        0.0s
 => [internal] load build context                                                                                                                                                                                                      0.0s
 => => transferring context: 426B                                                                                                                                                                                                      0.0s
 => CACHED [1/3] FROM docker.io/apache/airflow:2.10.1                                                                                                                                                                                  0.0s
 => [2/3] COPY ./requirements.txt /opt/airflow/requirements.txt                                                                                                                                                                        0.0s
 => [3/3] RUN pip install -r /opt/airflow/requirements.txt                                                                                                                                                                             3.5s
 => exporting to image                                                                                                                                                                                                                 0.0s 
 => => exporting layers                                                                                                                                                                                                                0.0s 
 => => writing image sha256:38d6d22e6f57cd23e3dde8ddd3307caa3e72094331f8d3d420af8b270193d690                                                                                                                                           0.0s 
 => => naming to docker.io/library/airflow_test                                                                                                                                                                                        0.0s

 

그래서 결국 현재 실행중인 airflow 를 전부 종료시키고나서 기존에 사용하던 모든 docker 이미지와 볼륜 등 시스템에 남아있는 부분들을 다 제거해주었다.

docker system prune -a -f

 

그리고 나서 다시 빌드를 해주었더니... 정상적으로 빌드가 되었고 실행도 정상적으로 동작하는 것을 확인했다.

 

결론

결론은 기존에 사용중인 이미지에 문제가 있었던 것 같고 기존에 사용하던 이미지를 제거하고 다시 빌드해주니 정상적으로 빌드가 되었다.

진작에... 다 지우고 새로 빌드할 걸 그랬나보다. 그래도 이번 문제를 확인하면서 많은 고민을 했었고 결과적으로 좋게 잘 해결되었으니 다행이라고 생각한다. ㅎㅎ