-
[Docker] 3. Containerizing - Dockerfile로 도커 이미지 만들기Docker 2024. 3. 8. 21:38
Containerizing(컨테이너화)
응용 프로그램과 그에 필요한 모든 종속성을 컨테이너로 묶어서 효율적으로 배포 및 실행할 수 있게 해주는 과정
도커 이미지를 만드는 과정이다.
Dockerfile이 Docker image로 빌드되는 과정
현재 디렉토리 상태
app.js와 package.json 등 node.js 앱을 만들기 위한 파일들과 Dockerfile이 있다.
Dockerfile 코드를 살펴보자.
Dockerfile 구성
- Dockerfile은 맨윗줄부터 맨 아랫줄까지 한줄씩 파싱되어 실행된다.
- 주석(#)이 아닌 줄은 모두 실행되어야 하는 명령어이다. 대소문자를 구별하지 않지만 명령어의 이름은 대문자로만 이루어지는게 보기 편하다.
위의 Dockerfile 각 명령어별 설명
1. FROM alpine
이미지의 맨 아래 레이어에 alpine OS가 쌓인다.
2. LABEL
키-값 쌍으로 커스텀 메타데이터를 담는데 사용된다.
3. Run apk add --update nodejs npm curl
Alpine apk 패키지를 이용해서 nodejs와 npm을 설치하여 레이어를 생성한다.
4. Copy . /src
현재 디렉토리의 app 파일들을 ./src로 복사해주는 레이어를 생성한다.
5. WORKDIR /src
작업공간을 /src로 설정한다.
따로 레이어를 만들어 저장하지 않고, 이미지의 config 메타데이터에 더해진다.
6. RUN npm install
WORKDIR로 설정했던 /src 폴더에 이전 레이어를 쌓을 때 설치한 npm을 이용해서 의존성 라이브러리들을 전부 받아오는 레이어를 생성한다.
7. EXPOSE 8080
TCP 포트 8080을 열어놓는다. 이미지의 메타데이터에 더해진다.
8. ENTRYPOINT["node", "./app.js"]
컨테이너가 실행해야 하는 파일을 설정한다. 이미지의 메타데이터로 더해진다.
Dockerfile을 이용해 도커 이미지를 빌드해보자.
docker image build -t web:latest .
- 현재 위치를 빌드 컨텍스트로 삼고, 해당 영역 내에 존재하는 Dockerfile을 읽어들여 이미지를 빌드하겠다.
컨테이너를 실행시켜보자.
docker container run -d --name c1 -p 80:8080 web:latest
- 호스트의 80번 포트로 들어오는 요청을 컨테이너의 8080으로 향하게 한다.
- 이미 호스트에서 포트번호 80을 다른 용도로 사용중이라면, 사용하지 않는 포트번호로 대체한다.
컨테이너 실행 결과
- nodejs 앱 컨테이너가 실행중이다.
localhost:80으로 접속해보자
- 잘 뜬다.
위 설명대로 이미지가 레이어를 쌓았는지 확인해보자.
docker image history web:latest
- SIZE가 0B가 아닌 명령어들은 레이어로 생성된 것들이다.
도커 이미지는 크면 안좋다. 프로덕션을 구동하는 데 꼭 필요한 재료들만 이미지에 담아야 좋다. 문제는 이미지를 작게 유지하는게 어렵다는 것이다. Dockerfile에 RUN 명령어를 추가할 때마다 이미지에 새 레이어가 하나가 생긴다.
또 다른 문제는 빌드시점때만 사용되는 도구들 역시 이미지에 쌓인다는 것이다. 이 도구들은 프로덕션 레벨에서는 사용되지 않기 때문에 이미지 크기가 커지는 요인이다.
프로덕션 이미지 크기 줄이는 방법 - Multi stage
- FROM 명령어는 stage를 생성하는데, 여러개의 FROM을 사용해서 이전 stage의 데이터를 복사해 오는 기법
Multi stage 적용된 Dockerfile 예시
- FROM node:latest AS storefront
- FROM maven:latest AS appserver
- FROM java:8-jdk-alpine
이렇게 총 3개의 FROM이 있고 세번째 FROM을 보면 COPY 명령어가 있는데 이전 FROM을 통해서 생성한 빌드 결과물 중 필요한 것만 복사해오는 과정이다.
빌드 결과
하나의 Dockerfile이 6개의 이미지를 만들었고, 최종 생성된 프로덕션 이미지는 multi:stage 이미지이다.
'Docker' 카테고리의 다른 글
[Docker] Security in Docker (0) 2024.03.08 [Docker] Docker overlay networking (0) 2024.03.08 [Docker] Swarm mode (0) 2024.03.08 [Docker] 2. 도커 이미지(Docker Image) 3분 이해 (1) 2024.02.23 [Docker] 1. 도커Docker를 왜 만들었을까? - 도커 큰그림 그리기 (0) 2024.02.23