🚈실시간 기차 예매 서비스 프로젝트의 Docker 관련 트러블슈팅
2025. 5. 26. 01:05

1.Local과 Docker의 환경변수 설정 차이

  • 문제상황 : 기존에는 application.properties 파일과 intelliJ에서 설정한 환경변수를 사용하여 local 환경에서 문제가 없었으나, Docker에서는 해당 환경변수를 제대로 불러오지 못하는 문제가 발생함
  • 원인 : Docker는 자체 컨테이너 환경에서 실행되기 때문에, 로컬 환경에서 설정한 환경변수는 컨테이너 내부로 전달되지 않음. (특히 intelliJ에 설정한 환경변수는 프로그램에만 입력 된 것!) 즉, Docker환경에서는 환경 변수 설정을 달리 해주어야 한다는 것을 인지함. 특히 어떤 방식으로 docker라는 배에 환경변수를 싣을지 방법 또한 고민해보아야 함
  • 해결책

1. 도커의 상태를 관리하는 docker-compose 파일 내에서 .env 파일을 통해 docker의 환경변수를 주입하도록 설정함

[docker-compose.yml]

app:
  env_file:
    - .env

2. 또한 local용과 docker용 application.properties 파일을 구분하여 환경별로 관리하도록 설정함

  • 특히 db 접속 주소가 환경마다 달라지기 때문에, 파일의 분리가 필수적이었음
[application-docker.properties 파일]
jdbc:mysql://mysql:3306/${DB_NAME}

[application-local.properties 파일]
jdbc:mysql://localhost:3306/${DB_NAME}

3. `SPRING_PROFILES_ACTIVE` 값을 통해 실행 시점에 어떤 설정 파일을 참조할지 명시하였음


2. docker 이미지 빌드

  • 문제 인식 : `docker compose build` 명령어 실행 시, “복사 대상 파일을 찾을 수 없다”는 에러 발생

  • 문제 상황
    • 파일 copy 단계에서 JAR 파일을 찾지 못해서 복사에 실패함
    • 하지만 로컬에서는 build/libs 폴더에 JAR 파일이 존재함
  • 원인 : .dockerignore에 의해 build/ 폴더가 제외되면서, 해당 폴더가 Build Context에서 제외됨. Docker는 .dockerignore 에 의해 제외된 폴더는 Build Context로 전달받지 않기 때문에 COPY 대상인 SNAPSHOT.jar 파일이 Docker 입장에선 존재하지 않는 파일이 되어 에러 발생한 것.
  • 해결책 : .dockerignore 파일에서 build/ 항목을 삭제하고, 다시 /gradlew build 로 jar 파일 생성한 후, docker compose build 로 이미지를 생성함.
  • 회고 : Docker 이미지 생성 과정과 .dockerignore의 동작에 대한 이해 부족에서 비롯된 에러였음. 앞으로 Docker를 생성할 때 필요한, 이미지에 넣어야 할 파일이 있다면, .dockerignore 파일에 함부로 입력하지 말 것!
더보기

** 참고사항

  • docker compose build : 도커 이미지를 생성하는 명령어
  • Docker의 Build Context : docker build / docker compose build 를 실행하면 현재 디렉토리의 내용을 Docker 엔진에 압축해서 전송함. 이때 전송되는 파일/폴더들이 Build Context
  • .dockerignore 파일 : 여기에 적힌 항목들은 Build Context에서 제외됨
  • Dockerfile의 COPY build/libs/five-rock-run-0.0.1-SNAPSHOT.jar app.jar : Build Context에 포함된 파일만 복사 가능

3. 팀원간의 운영체제 차이로 인한 Docker 빌드 실패

  • 문제인식 : 윈도우 환경에서 Docker가 정상 실행되었으나, macOS를 사용하는 팀원들의 로컬 환경에서는 동일한 Dockerfile로 실행시 빌드가 실패함 (Docker Desktop을 사용하여 로컬에서 직접 컨테이너 실행을 테스트하던 단계)
  • 문제 원인 : docker 공식 사이트(https://hub.docker.com/_/eclipse-temurin)에서 확인해보니, alpine 태그는 특정 OS에만 제공되며, 리눅스 기반 환경에서만 정상 작동한다고 명시되어 있음. 이는 macOS에서 실행할 수 없는 이미지였음.
[dockerfile]

FROM eclipse-temurin:17-jre-alpine
  • 해결책 : `-alpine` 태그를 제거하고, 수정된 Dockerfile을 깃에 푸쉬함. 이후 모든 운영체제에서 정상적으로 컨테이너가 실행되었음
  • 회고 : 운영체제에 따라 Docker 이미지가 호환되지 않을 수 있기 때문에, 공식 사이트를 참고하여 지원하는 태그와 OS를 사전에 확인해야 할 필요성을 느꼈음. 또한 프로젝트 초기 단계에서는 공통 환경 설정을 정리해두는 것이 중요하기 때문에, 팀원 모두가 동일한 Docker 환경을 갖출 수 있도록  readme 문서 가이드나 .env 파일을 관리하는 것도 방법이 될 듯 함.

4. Docker 기반 EC2 서버에서 MySQL 컨테이너 기동 실패

  • 문제 인식 : 기존에 잘 실행되던 github actions에서 test 실패함. 에러코드를 분석하니 파일을 EC2로 복사하는 과정에서 실패했다고 함. postman에서도 서버에서 refused 되었다는 에러 메세지를 확인하고, docker가 정상적으로 실행되고 있지 않는 문제임을 확신하였음. 
  • 문제 원인 : AWS의 인스턴스에서 실행되고 있는 docker를 확인해보니, db가 정상적으로 실행되고 있지 않았음. `docker logs mysql` 명령어를 통해서 mysql 컨테이너 내부의 에러 코드를 확인한 결과, EC2 서버의 루트 디스크 공간 부족으로 인해 db에 필요한 데이터 파일을 생성하지 못해서 db가 종료된 상황이였음. 추가적으로 `df -h`로 디스크 공간을 확인해보니, 디렉토리 디스크 공간이 100% 사용중이였음.

파티션이 100% 사용중인 것 확인

  • 해결책 : 디스크 공간 확보 후,  컨테이너 재가동
// 디스크 공간 확보
docker container prune -f
docker image prune -a -f
docker volume prune -f
docker builder prune -a -f
sudo journalctl --vacuum-time=1d

// 디스크 여유공간 확보 (사용률이 100%에서 31%로 감소함)
df -h

// 컨테이너 재가동
docker-compose down -v
docker-compose build
docker-compose up -d

리소스 삭제후, 디스크 공간이 확보된 상황

  • 결과 : 다시 github actions 및 서버가 정상적으로 구동되는 것을 확인함

  • 예방 : aws에서 docker를 정상적으로 실행시켜뒀는데도 디스크 공간이 부족해서 자동으로 컨테이너가 exit 될 수 있다는 것을 알게 되었음. 주기적으로 EC2 인스턴스의 디스크 크기를 모니터링하고 불필요한 리소스를 삭제할 필요성을 느낌

 

LIST