docker 공부 시작하기 [spring-boot] 도커파일에 작성되는 명령어 알아보기- (2)

xxx-sj·2023년 11월 22일
0

도커

목록 보기
2/3

📕명령어 비교하기

이 전 글을 작성하면서 비슷한 역할을 하는 명령어들이 있는 것 같아서 이 글에서는 해당 명령어들을 정리해보려 합니다.

📙 RUN, CMD, ENTRYPOINT

📒RUN

RUNDockerfile에서 imagebuild하는 순간 실행되는 명령어 입니다.
RUN 명령어는 라이브러리 설치 시 주로 사용됩니다.

#Dockerfile
FROM ...
RUN npm install

📒CMD

CMDimage에서 container를 생성하여 실행할 시 수행됩니다.

FROM openjdk:11-jdk
CMD ["echo", "CMD test"]

📒ENTRYPOINT

CMD와 비슷합니다. container가 생성되고 최초로 실행할 때 수행되는 명령어 입니다.

#Dockerfile

FROM openjdk:11-jdk
CMD ["echo", "CMD test"]
ENTRYPOINT ["echo", "entry point test"]

해당 파일을 실행해보면 실행순서는 ENTRYPOINT 다음 CMD가 실행되는 것 같다..

📒 CMD, ENTRYPOINT 차이

동일하게 명령어를 실행하는 것 같은데 차이점은 무엇일까?
ENTRYPOINT는 항상 실행이 되고, CMDdocker run 할때 변경이 가능합니다.

#Dockerfile

FROM openjdk:11-jdk
CMD ["echo", "CMD test"]
ENTRYPOINT ["echo", "entry point test"]

Dockerfile에 CMD를 정의했음에도 docker run 할 때 명령어를 추가적으로 추가해서 실행하니 Dockerfile 에 정의한 CMD 명령어가 override되는 것을 볼 수 있다 물론 ENTRYPOINTrun 할때 옵션으로 override 가능하다.

📙 COPY, ADD

둘 다 Host OS에서 파일 또는 디렉토리를 컨테이너 안으로 복사하는 것이다.

COPY의 경우 Host OS에서 컨테이너 안으로 복사만 가능하지만, ADD의 경우 원격 파일 다운로드 또는 압축 헤제 등과 같은 기능을 갖고 있습니다. Host OS에서 컨테이너로 간단히 복사 시 COPY를 사용합니다.

#Dockerfile

COPY test.sh /app/copy/test.sh
ADD test.sh /app/add/test.sh

ADD 의 경우 URL을 통해 다운로드가 가능합니다.

ADD http://.... /app/add/url/index.html

📙ENV, ARG

ARGDockerfile에서만 사용이 가능하고, ENVDockerfile 이외에도 컨테이너에서도 환경변수로 사용이 가능하다.

#Dockerfile

# ENV [key] [value]
ENV test test
ENV test2 test2

#ENV [key]=[value] 
ENV test=test
ENV test2=test2

#ARG
ARG test=test
ARG test2=test2

다음으로 작성한 Dockerfile로 빌드된 이미지를 가지고 컨테이너를 실행하면 다음과 같다.

FROM openjdk:11-jdk
ARG test="test1111"
ENV test2="test2222"
CMD echo ">>> $test"

CMD 를 통해 ARG 변수를 출력해보면 아무것도 찍히지 않는것을 볼 수 있다. 즉, ARGDockerfile 내에서만 사용되고 그 이후에는 사용되지 않는다.

다음으로는 동일하게 하되, ENV 변수의 값을 사용해서 출력해보겠습니다.

#Dockerfile

FROM openjdk:11-jdk
ARG test="test1111"
ENV test2="test2222"
CMD echo ">>>> $test2"

ARG와는 반대로 출력이 잘 되는것을 볼 수 있습니다. 즉, ENV는 환경변수로 컨테이너 내에 환경변수로 저장되어있는 것을 볼 수 있습니다.

📙EXPOSE

#Dockerfile

FROM openjdk:11-jdk
ARG PATH=./build/libs
WORKDIR /app
EXPOSE 8081
COPY ${PATH}/docker-example-0.0.1-SNAPSHOT.jar ${PATH}/docker-example-0.0.1-SNAPSHOT.jar
CMD ["java", "-jar", "./build/libs/docker-example-0.0.1-SNAPSHOT.jar"]

EXPOSE는 해당 이미지를 가지고 만든컨테이너EXPOSE에 명시된 포트를 수신할 것 이라는 것과 같습니다.
하지만 아무런 옵션을 주지 않고 컨테이너를 실행하게 되면 해당포트만 열려있을 뿐 Host OS와 바인딩되어있거나 하지 않습니다.

docker run 명령어 실행 시 옵션으로 -P를 주게되면 Host OS에서 랜덤 포트EXPOSE에 명시한 포트바인딩 됩니다.

docker run -P [image-name]

기존에 알고있던 옵션 -p [host-port]:[container-port] 를 통해서도 포트바인딩할 수 있습니다.

두 개의 다른점은 EXPOSE로 명시한 포트같은 경우는 -P 옵션을 통해 랜덤 포트바인딩 된다는 점 이고, -p [host-port]:[container-port]를 통해 바인딩하는 경우는 명시적으로 바인딩할 수 있다는 점입니다.

📙추가적인 테스트

만약 다음과 같은 경우에는 어떻게 될까?

  • EXPOSE에 명시한 포트-p []:[]를 통해 바인딩하면 어떻게 될까?
  • EXPOSE포트를 명시한 후 -P 옵션과 -p []:[]을 같이 주면 어떻게 될까?
  • EXPOSE포트를 명시한 후 -P옵션과 -p []:[]옵션을 같이 사용하되, -p []:[] 옵션에서 다른 포트를 바인딩하면 어떻게 될까?

📒 EXPOSE와 같은 포트 바인딩해보기

EXPOSE에 명시한 포트와 같은 포트를 -p 옵션을 통해 바인딩하면 다음과 같습니다.

#Dockerfile 

FROM openjdk:11-jdk
ARG PATH=./build/libs
WORKDIR /app
EXPOSE 8081
COPY ${PATH}/docker-example-0.0.1-SNAPSHOT.jar ${PATH}/docker-example-0.0.1-SNAPSHOT.jar
CMD ["java", "-jar", "./build/libs/docker-example-0.0.1-SNAPSHOT.jar"]

docker run -p 8081:8081 as

Host OS 8081컨테이너 8081과 바인딩 된 것을 볼 수 있다.

📒 -P 옵션과 -p 같이 사용하기

-P옵션과 -p []:[]를 같이 사용하면 다음과 같습니다.

docker run -P -p 8081:8081 as

위와 동일한 것을 볼 수 있습니다.

📒 그렇다면 -p 옵션에서 다른 포트 바인딩 시엔??

이번엔 -P-p를 같이 쓰되, -p옵션에서 다른 컨테이너 포트를 바인딩 해보겠습니다.

docker run -P -p 10888:8088 as

컨테이너 포트를 변경해서 바인딩할 경우, -P 옵션에 의해 랜덤 포트와 바인딩 되고, -p 옵션은 따로 108888088이 바인딩 된 것을 볼 수 있습니다.

📙VOLUME, BIND MOUNT

Docker에서 컨테이너생명주기와 관계없이 데이터를 영속적으로 저장을 해야합니다. 또는 많은 경우 여러 개의 컨테이너가 하나의 저장 공간을 공유해서 데이터를 읽거나 써야 합니다.
Docker는 이에 대해 2가지 옵션인VOLUMEBIND MOUNT를 제공합니다.

📒VOLUME

docker volume ls를 통해 생성된 volume의 리스트를 볼수 있습니다.

docker inspect [volume] 을 통해 volume의 내용을 자세히 볼 수 있습니다.

📒VOLUME 생성하기

VOLUME생성 할 때는 docker volume create [volume-name] 으로 생성한다.

docker volume create vol-t


📒컨테이너에 VOLUME 마운트하기

컨테이너가 볼륨을 사용하기 위해서는 볼륨컨테이너마운트해줘야 합니다.
마운트하기 위해서는 -v [volume-name]:[container-location] 옵션을 추가합니다.

docker run -p 8081:8081 -v vol-t:/app as

docker inspect [container-name] 을 통해 Mounts부분을 보면 다음과 되어있는 것을 볼 수 있습니다.

-v 옵션이 없는 컨테이너는 다음과 같이 Mounts 부분이 비어있습니다.

docker run -p 8081:8081 as

volume다른 컨테이너에도 마운트가 가능하기 때문에 컨테이너데이터 공유가 가능해집니다.

📒VOLUME 삭제

VOLUME 삭제 시에는 마운트 되어있는 컨테이너삭제 한 후 VOLUME을 삭제해야 합니다.

📒BIND MOUNT

바인드 마운트는 Host OS 파일 시스템의 특정 경로를 컨테이너로 바로 마운트 할 수 있습니다.
컨테이너 실행 시 옵션으로 -v [host location(file or directory)]:[container-location] 추가해주면 됩니다.

docker run -p 8081:8081 -v $(pwd):/app as

출처

https://nirsa.tistory.com/69
https://nirsa.tistory.com/70?category=868315
https://soft.plusblog.co.kr/139#google_vignette
https://tech.cloudmt.co.kr/2022/06/29/%EB%8F%84%EC%BB%A4%EC%99%80-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%9D%98-%EC%9D%B4%ED%95%B4-3-3-docker-image-dockerfile-docker-compose/
https://www.daleseo.com/docker-volumes-bind-mounts/#google_vignette
https://seosh817.tistory.com/374

profile
틀려도 일단 기록하자

0개의 댓글