Docker Image & Container
Table of Contents
Images & Containers#
Image#
이미지는 설계도이다. 코드와 필요한 환경을 모두 포함하고 있다. Dockerfile 을 이용해서 Docker Image 를 만들 수 도 있고, Dockerhub 에 있는 이미지를 pull 해서 사용할 수 있다.
위를 보면 docker 내에서 run 한 node와 local 에서 Run 한 node의 version 이 다르다. 즉 로컬 환경과 독립적으로 도커 컨테이너 내에서 독립적으로 노드가 실행된 것이다.Dockerfile 을 이용해서 이미지 만들기
FROM node
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
CMD ["node","server.js"]
이미지는 읽기 전용이다. 소스코드를 변경하고, 다시 localhost 사이트에 들어가도 변경 사항이 반영되지 않는다! 왜냐면 이미지는 복사한 시점에서 소스코드의 스냅샷을 만든다. 업데이트한 Source code 를 반영하려면 image rebuild 해야 한다. docker build .
다시 실행하면 새로운 ID 할당한다.
Container#
컨데이터는 돌아가는 unit of software 이다. run 명령어로 실행한다 (docker run node
). 이미지를 이용해서 빌드 한다.
Image Layer#
이미지는 layer based architecture 이다. 처음 dockerfile 을 이용해서 docker build 를 한 후 , 소스 코드를 수정 후 두번째로 docker build .
를 하면 굉장히 빨리 되는데, 이것은 이전에 만들어 놓은 cache 를 사용하기 때문이다.
변경 사항 이후에 모든 Instruction 은 모두 다시 실행한다. 위의 Dockerfile 을 다시 보자.
# Base image가져오기 (여기서는 node)
FROM node
#all the commands 가 app 폴더 내에서 실행된다.
WORKDIR /app
# which file should go into the image ?
# COPY . . -> 첫번쨰 점: dockerfile파일을 포함하고있는 폴더 내 모든 파일 , 두번째 점: 그 파일을 저장해야 하는 이미지 내부의 경로
# (첫번째)Host file system , (두번째)Image/container file system
COPY . /app
RUN npm install
#local 에 실행되고 있는 port 노출 (선택사항)
EXPOSE 80
#RUN <-> CMD: 이미지가 생성될때 위 명령어 실행x, container 가 시작할때 실행함
CMD ["node","server.js"]
소스코드를 변경하면 , COPY ./app
이후에 모든 명령어를 다시 실행하지만, 사실 RUN npm install
은 다시 실행할 필요가 없다! 이럴때는, 아래와 같이 COPY 를 2번에 걸쳐서 나누어서 해주면 된다. 소스코드만 변경되면, COPY ./app
이후의 명령어들만 다시 실행해서 빌드하므로, RUN npm install
은 이미 캐시되어 있는 데이터를 사용한다.
# Base image가져오기 (여기서는 node)
FROM node
#all the commands 가 app 폴더 내에서 실행된다.
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
#local 에 실행되고 있는 port 노출 (선택사항)
EXPOSE 80
#RUN <-> CMD: 이미지가 생성될때 위 명령어 실행x, container 가 시작할때 실행함
CMD ["node","server.js"]
Managing Images & Containers#
Container 중지 & 재시작
docer run 은 아래 새로운 명령어 입력창이 뜨지 않는다. 즉, Attached 되어 있다. 이것은 container 의 output 을 듣고 있는 상태인 것이다 (log들이 콘솔에 출력된다).docker run
: 새로운 docker 를 시작docker start <container ID>
: run 했던 conatainer 재시작docker start 를 입력하면, 실행되고 새로운 명령어 창이 뜬다. 즉, detached 되어 있다 (log 가 콘솔창에 뜨지 않는다). detached 된 것을 다시 attach 할 수 도 있다 ->
docker attach <container ID>
.docker logs
를 통해 출력된 과거 log 들을 볼 수 ㅣ있다. 과거의 로그, 앞으로의 로그들 모두 보고 싶으면docker logs -f <contaier ID>
를 입력하면 된다.
이미 실행중인 container 에 연결하기
디폴트로 -d
없이 컨테이너를 실행하면, “attached” 모드로 실행된다.
Interactive Mode 로 들어가기
docker run -it <Container_ID>
: interact 할 수 있게 만들어줌 (input 입력 가능!)docker start -a -i <Container_ID>
: restart 하면서 Input 을 입력받을 수 있게 해줌
Image & Container 삭제하기
docker rm <Container_ID1> <Container_ID2> <Container_ID3>
docker images
: 가지고 있는 image 표시docker rmi <IMAGE ID>
: image 제거- 이미지를 없애기 전에 Container 를 없애야 한다.
docker image prune
: 안쓰는 image 모두 제거
중지된 Container 자동 제거하기
docker run -p 3000:80 -d --rm <IMAGE ID>
: docker stop 하면 자동적으로 container 를 remove 한다.docker stop <container name>
→ 컨테이너가 중지되면 자동으로 제거된다 !
이미지 검사
docker inspect <Image ID>
Sharing Images & Containers#
이미지를 가지고 있는 누구나, 이미지를 바탕으로 컨테이너를 생성할 수 있다. 그렇다면, 이미지를 공유하면 된다 !
Github 와 비슷하게, 이미지를 push 하고 pull 할 수 있는 DockerHub 가 존재한다. DockerHub 는 공식적인 이미지 저장소이다. 여기서 남들이 올려놓은 public 이미지, 또는 official 이미지를 pull 할 수 있다.
docker push <IMAGE NAME>
: DockerHub 에 이미지 올리기docker pull <IMAGE NAME>
: DockerHub 에서 이미지 가져오기
중요한 것은, 내 레포에 이미지를 올릴 때는 <username>/<Image name>
형태로 이미지 이름을 지어야 한다.
Docker hub에서 새로운 repository 를 만든다.
Image 이름을
<USER NAME>/<REPOSITORY NAME>
으로 만든다.docker build -t soeunuhm/node-hello-world .
push 할때는 dockerhub 에 login 되어있어야 하지만, pull은 누구든지 할 수 있다 !!docker push soeunuhm/node-hello-world
docker build -t myimage #이미지 생성(이름: myimage)
docker run —name mycontainer myimage #컨테이너 시작 (컨테이너 이름: mycontainer)
docker stop mycontainer #컨테이너 중지
Summary#
Docker 는 결국 Image & Container 가 가장 중요하다 !! 이미지는 컨테이너를 만들기 위한 템플릿이고, 이미지를 기반으로 다수의 컨테이너를 만들 수 있다. 이미지는 DockerHub 에서 다운 받거나 (docker pull
) , Dockerfile 을 이용해서 만들 수 있다 (docker build
).
Dockerfile 의 구조는 다 비슷비슷하다. Image 는 캐싱을 통해 빌드 속도를 최적화하고, 재사용성을 위해 레이어 기반 구조(1 instruction = 1 layer)이다. 따라서 Dockerfile 을 작성하는 순서도 중요하다.
컨테이너는 docker run IMAGE
명령어를 통해 실행할 수 있는데, 다양한 옵션을 추가할 수 있다. 어떤 옵션이 있는지는 docker run -help
를 통해 볼 수 있다.
모든 컨테이너를 리스트 하고(docker ps
) , 제거하고 (docker rm
) 멈추고 (docker stop
) 시작할 수 있다 (docker start
)
이미지 또한 리스트 하고 (docker images
) , 제거하고 (docker rmi, docker image prune
) 공유할 수 있다 (docker push / pull
)
Reference#
- Udemy, Docker & Kubernetes sec.2