본문 바로가기

루퍼스/라이팅

[삽질기] Colima 까지 갔다가 설정 한 줄로 돌아온 건에 대하여 (feat. Testcontainers)

오늘의 이야기를 제미나이가 그림 한장으로 표현해줬다..

 

1. 문제 관측 / 발견 / 정의

"분명 내 터미널에선 Docker가 잘 되는데, 왜 테스트 코드만 돌리면 죽는 걸까?"

통합 테스트(@SpringBootTest) 실행 시 Testcontainers가 로컬 Docker 환경을 찾지 못하고 BadRequestException (Status 400)을 뱉으며 빌드가 실패하는 현상이 발생했다.

  • 현상:
    • 터미널(docker ps, docker info) 정상 동작
    • 테스트 실행 시 Could not find a valid Docker environment 오류 발생
    • Testcontainers가 docker-cli.sock 등 엉뚱한 소켓을 참조하거나, 연결 자체를 거부당함
  • 환경: macOS (M4 Air), Docker Desktop 사용

2. 다양한 시도

"안 되면 되게 하라"는 마음으로 소켓부터 런타임까지 모든 것을 의심하고 바꿔보았다.

  1. 소켓 경로 강제 지정 (.testcontainers.properties)
    • Docker Desktop의 기본 소켓 대신 docker.host를 직접 지정해 보았으나 실패...
  2. 환경변수 제어 (DOCKER_HOST)
    • DOCKER_HOST 환경변수를 unset 하거나 재설정해보았지만, 여전히 400 에러 발생...
  3. Docker 런타임 변경 (Docker Desktop → Colima)
    • "Docker Desktop의 네트워크 문제 아닐까?"라는 의심으로 대체제를 찾아 Colima 로 런타임을 변경
    • 하지만 이번엔 Ryuk 컨테이너(리소스 정리용)가 operation not supported 에러를 뱉으며 기동 실패
    • 원인: macOS 호스트의 소켓 경로와 Colima VM 내부의 소켓 경로 불일치로 인한 마운트 실패

3. 적용 / 채택한 방식

결과적으로 두 가지 해결책을 알게 되었다.

나는 우선적으로 통합테스트 환경을 구성하는데 급했으므로 Colima 환경 을 구현했고,

이후 Docker Desktop에서의 간단한 해결법도 알게 되었다.

A. Colima 환경 안정화 (내가 선택한 길)

호스트와 VM 간의 소켓 경로 차이를 Gradle 설정으로 해결했다.

  • DOCKER_HOST: 테스트 JVM이 Colima 엔진(호스트 경로)을 바라보게 설정.
  • TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE: 컨테이너 내부에서는 리눅스 표준 경로(/var/run/docker.sock)를 쓰도록 강제.
// build.gradle.kts
tasks.test {
    // ...
    environment("DOCKER_HOST", "unix://${System.getProperty("user.home")}/.colima/default/docker.sock")
    environment("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/var/run/docker.sock")
}

B. Docker Desktop 복귀 (깨달음의 길)

트러블슈팅 후, 슬랙에 올라온 다른분의 조언을 통해 Docker Desktop에서도 API 버전 호환성 설정 파일 하나면 해결됨을 확인했다....!!

# Docker Desktop 최신 버전과 Testcontainers 클라이언트 간 버전 불일치 해결
echo "api.version=1.44" > ~/.docker-java.properties

4. 결과

  • Colima 환경에서 ./gradlew test 실행 시 BUILD SUCCESSFUL 달성
  • 통합 테스트에 필요한 컨테이너가 정상적으로 라이프사이클(시작/종료)을 가짐
  • 이후 Docker Desktop 환경에서도 설정 파일 하나로 문제가 해결됨을 직접 검증 (ㅠㅠㅠ)

5. 회고 (가장 빠른 길은 돌아가는 길이었다)

처음에는 "진작 설정 한 줄(api.version)만 알았다면 시간을 아꼈을 텐데"라는 아쉬움도 있었다. 하지만 이 삽질 덕분에 얻은 것이 많다.

  • 단순히 도커를 쓰는 것을 넘어, Docker의 소켓 통신 구조(Unix Socket)와 호스트 vs VM 간 파일 시스템 마운트 차이를 이해하게 되었다.
  • 이제 Colima든 Docker Desktop 이든, 혹은 CI/CD 환경이든 Docker 관련 문제가 터지면 어디를 봐야 할지 알게 되었다.

 

p.s. 사실 퇴근 후에 "얼른 테스트만 돌리고 자야지" 했는데, 이 에러로 인해 새벽까지 씨름하느라 체력이 방전됐다.. (출근하자마자 커피)

공식 문서나 가이드를 좀 더 꼼꼼히 읽었더라면 수면 시간을 지킬 수 있었을텐데..

 

분명 읽었던 노션이였는데.. 앞으로 더 꼼꼼히 확인해야겠다 !!