Docker의 상대 경로 문제

임현규·2023년 3월 1일
0

Docker의 경로 문제

실행중인 터미널 위치에서 Dockerfile을 실행한다면 굉장히 쉽게 명령어를 통해 이미지를 build할 수 있다.

docker build -t my-java-app .

하지만 실제 Docker 프로젝트를 진행하다보면 다른 경로에 DockerFile들을 보관해야 하는 경우가 생긴다.

문제의 상황

java application에서 build후 프로젝트 root에 build/libs/app.jar 생성된 jar 파일을 Docker image로 빌드하는 작업을 수행한다고 하자. 이 때 해당 경로에 있는 app.jar를 COPY하며 실행 가능한 EntryPoint를 만든 이미지이다.

해당 Dockerfile의 예시이다.

# root/docker/java/Dockerfile-java
FROM openjdk:11-jdk-slim

WORKDIR /app

COPY build/libs/app.jar app.jar

ENV SERVER_MODE default
ENV PORT 8000
ENV LOCATION "/"

ENTRYPOINT ["java","-Dserver.port=${PORT}","-Dspring.profiles.active=${SERVER_MODE}", "-jar", "app.jar", "--spring.config.location=${LOCATION}"]

해당 Dockerfile은 root/docker/java/Dockerfile-java에 위치한다.

build 문제 해결하기

COPY는 build/libs/app.jar 를 요청하고 있다. COPY의 현재 경로는 root일 것이다. 만약 우리가 build 명령어를 사용하려면 어떻게 요청해야 할까?

만약 root 경로에 있다면

docker build -t myapp -f /docker/java/Dockerfile-java .

마지막 .은 docker-compose의 context라 보면 된다. 현재 경로 기준으로 실행되어야 하므로 .을 적는다

만약 root/docker/java 경로에서 실행한다면 어떻게 될까?

docker build -t myapp -f Dockerfile-java .

이렇게 설정하고 Dockerfile의 COPY 경로 앞에 ../../ 를 추가하면 이론상 될 것같다. 하지만 COPY를 실패한다. 그 이유는 마지막에 context가 .이면 root의 폴더는 캐치하지 못하고 root/docker/java 경로의 파일만 캐치한다. 그렇기 때문에 전혀 root/build를 인식할 수 없다. 가장 좋은 방법은 다음과 같다.

docker build -t myapp -f Dockerfile-java ../../

실행 경로 context을 root로 인식하게 되면 root 하위 디렉토리와 파일을 캐칭하기 때문에 동작하게 된다. 이것은 docker-compose.yml에서도 동일하게 적용된다.

version: "3"
services:
  java-api-server:
    build:
      context: ./docker/java
      dockerfile: Dockerfile-java
    ports:
      - "8080:8080"
    environment:
      PORT: 8080

해당 코드는 실패한다. ./build를 인식하지 못하기 때문이다. 이를 다음과 같이 바꾸면 동작한다.

version: "3"
services:
  java-api-server:
    build:
      context: ./
      dockerfile: ./docker/java/Dockerfile-java
    ports:
      - "8080:8080"
    environment:
      PORT: 8080
profile
엘 프사이 콩그루

0개의 댓글