현상, 에러 메시지

Error 발생 배경

개발 서버에서 Docker 기반으로 PostgreSQL + Tomcat 컨테이너를 띄우는 환경을 운영하고 있었다.
재빌드를 위해 Jenkins에서 Job을 실행했는데, 컨테이너 재생성 단계에서 postgres 서비스에서만 오류가 발생했다.

Error 메시지

ERROR: for postgres  'ContainerConfig'
Traceback (most recent call last):
  File "/usr/bin/docker-compose", line 33, in <module>
    sys.exit(load_entry_point('docker-compose==1.29.2', 'console_scripts', 'docker-compose')())
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 81, in main
    command_func()
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 203, in perform_command
    handler(command, command_options)
  File "/usr/lib/python3/dist-packages/compose/metrics/decorator.py", line 18, in wrapper
    result = fn(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 1186, in up
    to_attach = up(False)
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 1166, in up
    return self.project.up(
  File "/usr/lib/python3/dist-packages/compose/project.py", line 697, in up
    results, errors = parallel.parallel_execute(
  File "/usr/lib/python3/dist-packages/compose/parallel.py", line 108, in parallel_execute
    raise error_to_reraise
  File "/usr/lib/python3/dist-packages/compose/parallel.py", line 206, in producer
    result = func(obj)
  File "/usr/lib/python3/dist-packages/compose/service.py", line 679, in do
    return service.execute_convergence_plan(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 579, in execute_convergence_plan
    return self._execute_convergence_recreate(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 499, in _execute_convergence_recreate
    containers, errors = parallel_execute(
  File "/usr/lib/python3/dist-packages/compose/parallel.py", line 108, in parallel_execute
    raise error_to_reraise
  File "/usr/lib/python3/dist-packages/compose/parallel.py", line 206, in producer
    result = func(obj)
  File "/usr/lib/python3/dist-packages/compose/service.py", line 494, in recreate
    return self.recreate_container(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 612, in recreate_container
    new_container = self.create_container(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 330, in create_container
    container_options = self._get_container_create_options(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 921, in _get_container_create_options
    container_options, override_options = self._build_container_volume_options(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 960, in _build_container_volume_options
    binds, affinity = merge_volume_bindings(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 1548, in merge_volume_bindings
    old_volumes, old_mounts = get_container_data_volumes(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 1579, in get_container_data_volumes
    container.image_config['ContainerConfig'].get('Volumes') or {}
KeyError: 'ContainerConfig'

postgres 컨테이너를 재생성하는 단계에서 KeyError: 'ContainerConfig' 가 발생하면서 전체 docker-compose up 이 실패했다.

해결 시도

시도 1 : docker compose up으로 변경

빌드 스크립트와 콘솔 로그를 확인하다가 docker-compose up 방식으로 Job이 실행되는 것을 확인했다. 빌드 서버 관리자에게 연락해서 스크립트 상에서 docker-compose up 방식에서 docker compose up 로 변경했다.
하지만 이번에는 docker compose 명령어 자체를 인식을 못하는지 애꿎은 다른 옵션을 인식을 못하는 콘솔 로그를 확인했다.

시도 2 : docker-compose-plugin V2 버전 설치

서버 관리자와 함께 빌드 서버의 패키지 목록을 확인해 보니 Docker Compose Plugin가 설치되어있지 않았다. 그래서 docker compose 명령어를 인식하지 못했던 것이었다.
DockerDocs를 참고하여 아래의 명령어로 Docker Compose Plugin 설치를 시도했다.

sudo apt-get install docker-compose-plugin

눈에띄는 에러가 나오지는 않았지만 설치 완료되었다는 안내도 없고 아래 명령어로 확인했을 때는 docker compose 설치가 실패한 것을 알 수 있었다.

docker compose version

시도 3 : apt 업데이트(해결)

이후, 서버 전체 패키지를 업데이트하는 방향으로 접근했다.

sudo apt update

업데이트 후 docker compose 명령이 정상적으로 동작하는지 확인했다.

docker compose version

제대로 설치 된 것을 확인할 수 있었다.

원인

1차 원인

문제의 핵심은 docker-compose V1(Python 기반) 이 계속 사용되고 있었다는 점이었는데,
Jenkins Job 실행 시에 V1 베이스로 docker-compose up 방식으로 호출되고 있었다.
Docker Compose V1은 공식적으로 더 이상 지원되지 않기 때문에 Job에서 Docker Compose Plugin 기반의 V2 베이스로 실행되도록 docker compose up 방식으로 바꿨는데 이번엔 Docker Compose Plugin이 설치되어있지 않은 문제가 있었다.

Docker Compose V1 (docker-compose)은 Python 패키지였으나 아래의 이유로 개발을 중단했다고 한다.

  • Python 기반 유지보수의 비효율성
  • 최신 Docker API·Containerd·Volume·Network 구조와의 불일치
    V1 패키지는 제거되어서 최신 환경에서는 애초에 docker-compose이 불가능해졌다.

Compose V2는 Go 기반의 Docker plugin 방식으로 Docker Engine과 동일한 Go 코드로 안정적으로 연동된다고 한다.

2차 원인

아마 배포 서버의 환경이 모종의 이유로 Docker만 버전이 올라간 상황이고 Docker Compose Plugin을 따로 설정한 환경이 아닌 모양이었다.(나한테 관리자 권한이 있는 서버가 아니라 정확한 히스토리는 확인이 불가능했다) 그렇기에 혼자서 업그레이드 된 Docker는 docker-compose up V1 방식을 오류로 뱉으면서도docker compose up V2 방식은 실행이 안된 것.
apt 를 update해서 Docker Compose Plugin을 설치하여 최종적으로 해결할 수 있었다.