도커 A to Z - Docker 이미지 & 컨테이너

김상운(개발둥이)·2022년 9월 17일
0

도커 A to Z

목록 보기
2/5
post-thumbnail

이미지 vs 컨테이너

이미지

  • 컨테이너의 템플릿/청사진
  • 코드와 런타임시 필요로하는 툴을 가지고 있다.
  • 레이어 기반, 읽기 전용, 어플리케이션의 데이터는 저장되지 않는다.

컨테이너

  • 실행되고 있는 소프트웨어의 단위
  • 여러 컨테이너가 하나의 이미지로 부터 만들어 질 수 있다.
  • 최상위 레이어, 읽기/쓰기 가능, 어플리케이션 종료 시 데이터가 사라짐

하나의 이미지로 부터의 여러 컨테이너 예시

도커 이미지가 필요 시

크게 두가지 방법이 있다.

  1. 도커 허브를 통해서 이미 존재하는 이미지를 사용한다.
  2. 스스로 Dockerfile 을 작성하여 나만의 이미지를 만든다.

이미지 & 이미지 레이어

  • 레이어는 이미지들 사이에서 공유되어진다. (이는 도커 이미지를 작게 유지한다)
  • 도커의 이미지에는 레이어가 존재한다. 하나의 커스텀 이미지는 다른 이미지를 기반으로 존재할 수 있다.

중요! 모든 명령어(코드, 설정, 실행 명령어)는 하나의 레이어에 존재한다.

컨테이너는 하나의 이미지로 부터..

이미지를 다시 빌드하면 변경된 레이어만 다시 빌드가 된다.

무슨 말이지..?

예를들어 어플리케이션의 코드를 수정하여 다시 빌드 한다고 가정하자. 이미지는 여러 레이어로 이루어져 있는데 수정이 발생한 코드와 관련된 레이어만 다시 빌드된다. 이는 곧 캐시를 사용하여 빠르게 다시 빌드할 수 있다는 의미인데 레이어가 존재하는 이유이다.

Dockerfile 작성

Dockerfile
FROM node:14

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

EXPOSE 3000

CMD [ "node", "app.mjs" ]

위에서 부터 하나하나 설명을 하면

FROM

  • Dockerfile 은 FROM 으로 시작한다.
  • 노드 이미지를 기반으로 하여 우리의 자체 명령어와 자체 노드 앱을 포함한다.

WORKDIR

  • 도커의 모든 후속 명령이 해당 컨테이너 폴더 내부에서 실행될 것임을 알린다.
  • 도커 컨테이너&이미지의 파일 시스템에서 작업 디렉토리를 /app 으로 한다.

COPY

  • 현재 프로젝트 경로에 있는 Dockerfile 을 제외하고 이미지로 복사되어야 할 파일들이 있는 곳 지정
  • 작업 디렉토리를 /app 으로 하였기 때문에 ./ 의 상대 경로는 /app

RUN

  • 이미지가 실행될때 실행하는 명령어
  • 모든 로컬 파일을 이미지로 복사하여 npm install 한다. 도커 컨테이너 및 이미지의 작업 디렉토리에서 실행됨(/app)
  • 디폴트로 그 작업 디렉토리는 컨테이너 파일 시스템의 루트 폴더

EXPOSE

  • 도커 컨테이너의 포트를 80으로 지정 자체 네트워크가 있어 격리되어 있다.
  • 도커파일 마지막 명령전에 작성
  • 이 컨테이너가 시작될 때 우리의 로컬 시스템에 특정 포트를 노출하고 싶다라는 것을 명시 -> 문서이다 즉 아무것도 하지 않는다.

CMD

  • 이미지가 생성될 때 실행되지 않고 이미지를 기반으로 컨테이너가 실행될 때 실행
  • CMD node server.js 로도 작성 가능

docker 명령어

docker ps [-a]
  • 도커의 컨테이너 목록을 조회
  • -a: 실행중이 아닌 컨테이너도 조회

docker images
  • 도커 이미지를 조회

docker build [-t name:tag] .
  • 현재 디렉토리를 빌드하여 이미지를 만든다.
  • -t: 이미지에 이름과 태그를 부여한다.

docker run [-p] [3000:80] [-d] [--rm] [-it] [--name] [지정할 컨테이너 이름] 이미지 id,이미지 이름
  • 이미지 컨테이너 생성 & 실행
  • -p: publish 를 뜻한다. 로컬에서 3000번 포트로 게시함을 의미하며 80은 도커와 로컬간의 통신할 포트를 80으로 하며 EXPOSE 의 80을 사용한다.
  • -d: 백그라운드에서 돌아가게 한다.
  • --rm: 컨테이너 종료시 컨테이너 자동 삭제
  • --name: 컨테이너 이름 작성
  • -it: 인터렉티브 모드, 터미널 생성 컨테이너로 부터 입력을 받으며 컨테이너에 터미널을 생성한다.
    • i:인터렉티브 표준 입력을 열린 상태로 유지 attache 가 아닌경우에도 가능
    • t :tty 터미널을 생성

docker start [-ai] 컨테이너 id, 이름
  • -ai: docker start 는 기본적으로 detache 모드이기 때문에 -a 태그를 사용하며 i 는 인터렉티브 모드로 표준입력을 열린 상태로 유지한다.

docker stop 컨테이너 id, 이름
  • 컨테이너 실행을 중지

docker rmi 이미지 id, 이름
docker rm 컨테이너 id, 이름

docker image prune [-a]
docker container prune
  • 순서대로
  • 이미지 삭제
  • 컨테이너 삭제
  • 이미지 전체 삭제
  • 컨테이너 전체 삭제

이미지 삭제 시 해당 이미지의 실행중인 컨테이너가 있을 경우 컨테이너를 중지하여야 한다.


docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
  • 도커 이미지 이름, 태그 변경
  • 원본 이미지의 이름을 변경하는 것이 아닌 같은 이미지를 다른 이름과 태그로 복사, 같은 이미지이기 때문에 이미지 id 는 같다.

docker push/pull

도커 허브 에서 회원 가입 후 repository 를 만들자!

docker push IMAGE
  • 도커 이미지를 도커 허브에 push 한다.
  • 반드시 image 이름[:태그] 는 저장소의 username/repository name 과 같아야 한다.
docker pull IMAGE
  • docker hub 로 부터 이미지를 풀 한다.
  • docker run 명령어 실행 시 로컬에 이미지 없을 경우 docker hub 로 부터 풀해온다.
  • docker run 명령어 실행 시 로컬에 이미지가 있을 경우 docker hub 로 부터 풀 해오지 않아 최신 버전이 아닐 수 있다.
  • 최신 버전을 유지하기 위해 docker pull 하는것을 추천
profile
공부한 것을 잊지 않기 위해, 고민했던 흔적을 남겨 성장하기 위해 글을 씁니다.

0개의 댓글