이 전 글을 작성하면서 비슷한 역할을 하는 명령어들이 있는 것 같아서 이 글에서는 해당 명령어들을 정리해보려 합니다.
RUN
은Dockerfile
에서image
로build
하는 순간 실행되는 명령어 입니다.
RUN
명령어는 라이브러리 설치 시 주로 사용됩니다.
#Dockerfile
FROM ...
RUN npm install
CMD
는image
에서container
를 생성하여 실행할 시 수행됩니다.
FROM openjdk:11-jdk
CMD ["echo", "CMD test"]
CMD
와 비슷합니다.container
가 생성되고 최초로 실행할 때 수행되는 명령어 입니다.
#Dockerfile
FROM openjdk:11-jdk
CMD ["echo", "CMD test"]
ENTRYPOINT ["echo", "entry point test"]
해당 파일을 실행해보면 실행순서는
ENTRYPOINT
다음CMD
가 실행되는 것 같다..
동일하게 명령어를 실행하는 것 같은데 차이점은 무엇일까?
ENTRYPOINT
는 항상 실행이 되고,CMD
는docker run
할때 변경이 가능합니다.
#Dockerfile
FROM openjdk:11-jdk
CMD ["echo", "CMD test"]
ENTRYPOINT ["echo", "entry point test"]
Dockerfile에 CMD를 정의했음에도
docker run
할 때 명령어를 추가적으로 추가해서 실행하니Dockerfile
에 정의한CMD
명령어가 override되는 것을 볼 수 있다 물론ENTRYPOINT
도run
할때 옵션으로override
가능하다.
둘 다
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
ARG
는Dockerfile
에서만 사용이 가능하고,ENV
는Dockerfile
이외에도컨테이너
에서도환경변수
로 사용이 가능하다.
#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
변수를 출력해보면 아무것도 찍히지 않는것을 볼 수 있다. 즉,ARG
는Dockerfile
내에서만 사용되고 그 이후에는 사용되지 않는다.
다음으로는 동일하게 하되,
ENV
변수의 값을 사용해서 출력해보겠습니다.
#Dockerfile
FROM openjdk:11-jdk
ARG test="test1111"
ENV test2="test2222"
CMD echo ">>>> $test2"
ARG
와는 반대로 출력이 잘 되는것을 볼 수 있습니다. 즉,ENV
는 환경변수로컨테이너
내에환경변수
로 저장되어있는 것을 볼 수 있습니다.
#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
에 명시한포트
와 같은 포트를-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 []:[]
를 같이 사용하면 다음과 같습니다.
docker run -P -p 8081:8081 as
위와 동일한 것을 볼 수 있습니다.
이번엔
-P
와-p
를 같이 쓰되,-p
옵션에서 다른컨테이너
포트
를 바인딩 해보겠습니다.
docker run -P -p 10888:8088 as
컨테이너
포트
를 변경해서 바인딩할 경우,-P
옵션에 의해랜덤 포트
와 바인딩 되고,-p
옵션은 따로10888
과8088
이 바인딩 된 것을 볼 수 있습니다.
Docker에서
컨테이너
의생명주기
와 관계없이 데이터를 영속적으로 저장을 해야합니다. 또는 많은 경우 여러 개의컨테이너
가 하나의저장 공간
을 공유해서 데이터를 읽거나 써야 합니다.
Docker는 이에 대해 2가지 옵션인VOLUME
과BIND MOUNT
를 제공합니다.
docker volume ls
를 통해 생성된volume
의 리스트를 볼수 있습니다.
docker inspect [volume]
을 통해volume
의 내용을 자세히 볼 수 있습니다.
VOLUME
생성 할 때는docker volume create [volume-name]
으로 생성한다.
docker volume create vol-t
컨테이너가 볼륨을 사용하기 위해서는
볼륨
을컨테이너
에마운트
해줘야 합니다.
마운트
하기 위해서는-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
을 삭제해야 합니다.
바인드 마운트는
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