도커 입문 12 - Dockerfile(EntryPoint와 Workdir)

😎다룰 내용
도커 file 작성에 있어서 Workdir과 entrypoint에 대해서 알아보겠다
Workdit 설정과 entrypoint 도커 파일
해당 설정들을 이해하기 위한 실습을 진행해보자.
우선 도커 허브에 있는 아래의 이미지를 사용할 것이다.

지금부터는 도커 파일 작성과 실습 과정을 이어가보자.
아래의 링크에서 파일을 다운받고
https://github.com/codingspecialist/aws-v3/blob/release/aws-v3-0.0.3.jar
aws-v3/aws-v3-0.0.3.jar at release · codingspecialist/aws-v3
elastic bean stalk. Contribute to codingspecialist/aws-v3 development by creating an account on GitHub.
github.com

실습을 위해서 다음과 같은 파일 구조를 잡았다.

그리고 dockerfile의 내용을 아래와 같이 작성하였다.

FROM openjdk:11-jdk_slim
WORKDIR /app
COPY build/aws-v3-0.0.3.jar ./application.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev", "application.jar"]
# CMD ["--server.port=8080"]
작성한 각 코드 부분의 내용에 대해서 파악해보자,
(1) FROM openjdk:11-jdk_slim
FROM 이후에 이미지 명칭을 넣고 가져올 이미지를 지정하는 것이다.
(2) WORKDIR /app
도커 내부로 진입할 때, 진입 폴더가 어딘지 지정하는 설정이다.
예로 현재 사용중인 window에서 도커 내부로 진입하는 경우,
컨테이너에도 구성된 운영체제가 있을 것이다.
그리고 컨테이너 내부에서 작업을 수행할 경로는 /이름 의 형태로 있다.
그 중 /app으로 지정하는 것이며, 터미널을 통해 접근하면( exec / attach )해당 디렉토리로 접근하게 된다.

(3) COPY
그리고 COPY는 앞서 도커 file애 대한 학습에서 컨테이너 내부에 직접 코드가 옮겨지도록 하는 설정이었다.
따라서 현재 설정으로는 로컬의 build/aws-v3-0.0.3.jar을 ./application.jar의 명칭으로 컨테이너에 복사하는 역할을 한다.
( 그리고 ./은 현재 파일의 경로를 의미하는데, WORKDIR /app의 설정이니 ./의 경로는 /app이다. )
( +) ADD 압축파일.zip ./ —> ADD 명령어를 통해서도 가능한데 이는 압축이 풀린다.<압축파일을 던지는 경우> )
(4) ENTRYPOINT
컨테이너 실행에 있어서 실행 명령을 정의하는 선언문의 역할을 한다.
언뜻보면, CMD와 같은 역할을 하는 것처럼 보인다.
일단 현재 ENTRYPOINT가 어떤 역할을 수행하는 지 알아보자.
작성된 상태의 코드에서는 아래와 같은 명령어로 프로그램을 실행한다.
$ java -jar -Dspring.profiles.active=dev aws-v3-0.0.3.jar
✔️aws-v3-0.0.3.jar라는 Spring Boot 애플리케이션을 실행.
✔️Spring Boot의 dev 프로파일을 활성화하여 개발 환경 설정 적용.

해당 명령을 통해서 위처럼 스프링부트가 실행되는 모습을 볼 수 있다.
port 번호가 8081로 실행된다. 즉, 위와 같은 명령어를 통해 스프링부트를 실행하면 port번호 8081로 실행됨을 알 수 있다.
이미지로 build 후 실행하기
이번에는 이미지로 build하고 컨테이너를 실행하는 과정을 실습해보겠다.

빌드 과정을 끝내고나면 지정한 이미지명에 따라 이미지가 생성되어 있고
이를 컨테이너로 실행한다.

이제 컨테이너가 실행되고 8080port의 현재 띄운 컨테이너의 주소를 /aws/v3로 하였기에 여기에 접속하면 요청에 따른 응답을 브라우저에 잘 보여준다.

그리고 해당 브라우저에서 파라미터 number를 1,2,0,-1 등 다양한 입력을 주고 실행하면 똑같은 화면이 나온다.
여기서 < docker logs 컨테이너ID >를 실행하면 스프링부트가 실행되고 내부에서 실행된 로그를 살펴볼 수 있다.


cmd와 entrypoint의 차이
이번에는 cmd와 entrypoint의 차이를 파악하기 위해서 컨테이너를 중지하고 아래와 같은 과정을 거쳐서 실행해보자.

docker를 실행하는 과정에서 server의 port 번호를 5000번으로 입력해주었다.
그리고 로그를 살펴보면 5000번의 port에서 컨테이너가 실행되고 있는 모습이다.

이것이 CMD 명령으로 수행되는 것이다.
그런데 지금 포트포워딩을 8080:8081으로 지정하여 컨테이너 서버가 5000번이기에 접근할 방법이 없다.
따라서 컨테이너 내부에서 사용하는 port 번호와 포트포워딩을 모두 고려하여 명령어를 입력할 필요가 있다.

이처럼 컨테이너를 실행하고, 접근하면 다시 올바른 응답을 한다.
결국 ENTRYPOINT와 CMD는 도커 실행에 있어 실행 명령을 정의하는 선언문이다.
다만 ENTRYPOINT는 컨테이너 시작에 따른 Default 지정 값이다.
즉, ENTRYPOINT를 사용하여 컨테이너를 수행 명령을 지정한다면 반드시 ENTRYPOINT에서 지정한 명령을 수행하도록 지정된다.
한편, CMD는 컨테이너를 실행하는 시점에 인자값을 주면 지정한 Dockerfile의 값 대신하여 지정한 인자값으로 변경되어 실행한다.
위의 도커 파일을 경우로 CMD 명령 비활성화를 해제하면
$ java -jar -Dspring.profiles.active=dev aws-v3-0.0.3.jar --server.port=8080
이런 명령이 실행되는 것이다.
정리하자면, 도커의 수행에 따른 명확한 목적이 담긴 설정은 ENTRYPOINT에서 진행하고
그 안에서의 옵션 설정은 CMD를 통해서 구성한다.