230507 Docker

Docker


이번 포스팅에서는 Docker의 이미지 & 컨테이너(코어 빌딩 블록)에 대해 학습한 내용을 정리한다.

Images and Container

  • Pre-Built & Custom Images

  • Create & Manage containers

Images와 Container의 관계

  • Container : The running “unit of software”

  • Images : Templates / Blueprints for containers

Contains code + required tools/runtimes

이미지를 사용하여 여러 컨테이너(running instance)를 생성할 수 있다.

Finding / Creating Images

  • 이미지는 기존에 생성된 이미지를 사용하거나, Dockerhub에 업로드 되어있는 pre-built 이미지를 사용할 수 있다.
1
docker run --name node-image node

위의 명령을 통해 node pre-built 이미지를 Docker hub를 pull해서 로컬에 다운받을 수 있다.

1
docker ps -a

위의 명령을 통해서 도커가 생성한 모든 컨테이너 정보를 확인할 수 있다.

1
2
docker run -it node
# 쉘을 통해서 node container에 접근

나만의 CUSTOM DOCKER IMAGE를 생성하기 위해 Dockerfile을 작성할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 운영체제 레이어 SETTING
FROM node

WORKDIR /app

# 첫번째 .(dot) : 컨테이너 외부 경로로, Dockerfile이 위치한 경로를 의미한다.
# 두번째 .(dot) : 자체 내부 시스템
# 만약에 /app 폴더가 존재하지 않는경우에는 이미지와 컨테이너에 생성된다.
COPY . /app

# 기본적으로 도커 컨테이너 및 이미지의 WORKDIR에서 아래 명령이 실행된다.
RUN npm install

# DOCKER 컨테이너는 외부 로컬 시스템과 격리되어있다.
# 자체 내부 네트워크도 있기 때문에 외부 로컬 시스템에 노출시켜줘야 한다.
EXPOSE 80

# 서버 시작
# 아래 명령도 틀린건 아니지만, 이 이미지가 빌드될 때마다 실행되기 때문에
# 아래와 같이 실행하는 것은 올바르지 않다.
# 위에서 작성한 모든 것은 이미지 설정을 위한 명령으로, 도커 명령어이다.
# 이미지는 컨테이너의 템플릿이어야 한다. (이미지를 실행하는 것이 아닌, 이미지를 기반으로 컨테이너를 실행하는 것)
# RUN node server.js

# 컨테이너를 실행하는 경우에만 서버를 실행하기를 원하기 때문에
# 아래와 같이 명령을 실행하는 것이 맞다.
# RUN과 CMD의 차이는 CMD는 이미지가 생성될 때 실행되지 않고, 컨테이너가 실행될때 실행된다.
# 만약 명시된 CMD 명령이 없다면, BASE IMAGE의 CMD 명령이 실행되며, BASE IMAGE가 없고, CMD 이미지가 없다면 에러 메시지가 팝업된다.
CMD ["node", "server.js"]

그 다음 STEP은 위에서 작성한 Dockerfile의 스크립트 내용을 기준으로 Docker image를 만들어야 한다.

1
docker build --tag node-custom-app .

아래 명령으로 생성한 이미지(node-custom-app)를 사용하여 node-custom-app-container 도커 컨테이너를 80번 포트로 portforwarding하여 백그라운드로 실행한다.

1
2
# 실행할 Docker 이미지의 full name 말고, 만약 이름이 유일하다면, 부분이름으로 지정해서 사용할 수 있다.
docker run --name node-custom-app-container -p 80:80 -d node-custom-app

Dockerfile에서 EXPOSE 80은 문서화하는 목적으로 작성되었기 때문에 실제 컨테이너를 실행할때 위와같이 -p option을 통해 portforwarding 해줘야 한다. (EXPOSE 명령은 선택사항이지만 모범적인 사용법)

여지까지 기존 이미지인 노드 이미지를 기반으로 하는 커스텀 이미지를 docker build 명령을 통해서 생성하였고, docker run 명령을 통해서 해당 이미지를 기반으로 컨테이너를 띄웠다.

CUSTOM APP 코드 수정

커스텀 앱의 코드 일부를 수정했다면, 생성한 커스텀 이미지를 다시 빌드하여, 코드 복사과정을 다시 실행해야 한다.

한 번 빌드된 이미지는 잠겨있으며, 읽기 전용이 된다.

이미지는 레이어 기반 아키텍처(모든 명령이 레이어로 구성)로 되어있기 때문에 이미지를 빌드하는 과정에서 과거 실행되었던 부분에 대해서는 모든 명령 결과를 캐시하고, 이미지를 다시 빌드할때 명령을 다시 실행할 필요가 없으면, 캐시된 결과를 사용한다.

만약 특정 레이어가 변경되었다면, 변경된 레이어 후의 모든 레이어가 다시 빌드된다. 따라서 Dockerfile 내 레이어를 최적화 시키기 위해서는 우선적으로 package.json파일 개별적으로 복사하고, npm install 명령을 실행하고 반복적으로 코드 수정이 발생하는 부분에 대해서는 별도로 복사를 하는 과정을 작성하도록 하는 것이 좋다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 운영체제 레이어 SETTING
FROM node

WORKDIR /app

# 선 dependencies 파일 복사 및 설치
COPY package.json /app

RUN npm install


COPY . /app

EXPOSE 80

CMD ["node", "server.js"]

이 이미지를 기반으로 컨테이너를 실행하면, 컨테이너는 기본적으로 Dockerfile에 지정한 명령을 실행한 결과로 코드를 실행중인 애플리케이션인 이미지 위에 컨테이너 레이어를 새로 추가한다.

CUSTOM APP 코드 수정

Author

Lee Hyungi(이현기)

Posted on

2023-05-07

Updated on

2023-05-08

Licensed under

Comments