(Docker) Dockerfile COPY를 사용할 때의 문제

  • by

Docker Image는 여러 레이어로 구성됩니다.

도커 이미지는 빌드 시 Dockerfile의 각 명령어의 레이어를 만듭니다.


Docker는 매번 모든 레이어를 만들면 매우 느려질 수 있습니다.

따라서 Docker는 Docker Image 빌드 가속화 도커 캐시사용합니다.

첫 번째 이미지 빌드에서는 레이어별로 캐시를 만들고 이후 동일한 명령이 실행될 때 기존 레이어 재사용한다.

변경할 단계가 있는 경우 레이어가 다시 만들어집니다.

그러나 COPY와 같은 경우 jar 파일의 내용이 바뀌면 같은 명령으로도 Cache를 적용할 수 없다.

애플리케이션 코드를 직접 변경한 후 Dockerfile을 재구성하여 문제를 파악하고 솔루션을 배우십시오.

Docker에서 Spring Boot 프로젝트를 실행하는 프로세스는 다음과 같습니다.

1. 도커 파일 만들기
2. 도커 이미지 생성(build)
3. 도커 컨테이너 작성 및 프로젝트 실행(run)

1. Spirng boot 프로젝트를 실행하기 위한 Dockerfile

FROM openjdk:17-alpine

WORKDIR /usr/src/app

COPY ./build/libs/demo-0.0.1-SNAPSHOT.jar ./build/libs/demo-0.0.1-SNAPSHOT.jar

CMD ("java", "-jar", "./build/libs/demo-0.0.1-SNAPSHOT.jar")

2. Docker Image 만들기

$ docker build . -t springbootapp

첫 번째 Docker Image 빌드이므로 Dockerfile의 각 명령어의 레이어가 만들어집니다.


3. 애플리케이션 코드 변경 후 Docker Image 재생성

1. 애플리케이션 코드 변경 후 jar 파일 재생성


2. Dockerfile을 다시 빌드하고 Docker Image를 다시 만듭니다.


Dockerfile을 보면 COPY를 통해 jar 파일을 컨테이너 내부에 넣어 준다.

jar 파일에 변경사항이 있는 경우 jar 파일을 컨테이너에 넣어야 합니다.

이것에 의해 Docker Image가 새롭게 생성되는 것이다.

4. 솔루션: Docker Volume

Volume 는, 로컬에 있는 파일을 컨테이너내에서 참조할 수 있도록 하는 것입니다.

로컬로 jar 파일이 위치하고 있는 패스와 컨테이너 내부의 패스를 연결하면, 어플리케이션 코드 변경시에 컨테이너에 직접 반영된다.

COPY는 로컬에 있는 것을 도커 컨테이너 내부에 그대로 복사해 와서 따로 사용한다.

따라서, 어플리케이션 코드의 변경시에 Dockerfile을 빌드해 이미지를 재생성한 후, 컨테이너를 실행하지 않으면 변경이 반영된다.

$ docker run (옵션) -v (호스트 경로):(컨테이너 경로) (IMAGE 식별자)
$ docker run -p 5000:8080 -v $(pwd)/build/libs:/usr/src/app/build/libs springbootapp