이미지를 생성하는 방법
도커 파일을 사용하지 않을 경우
- 기본 이미지(우분투, CentOS 등) 기반 컨테이너 생성
- 환경 설치 후 컨테이너에서 잘 동작하는 것을 확인
- 컨테이너를 이미지로 커밋
단점
- 수작업으로 패키지를 설치해야함
- 환경설정을 할 때 어떤 과정을 거쳐야 하는지 알지 못함
도커 파일을 사용 할 경우
- 환경설정 할 때 수행해야 하는 명령어와 셸 스크립트를 하나의 파일에 기록하고 관리 할 수 있음
- 깃과 같은 개발 도구를 통해 애플리케이션의 빌드 및 배포를 자동화 할 수 있음
- 도커 허브에 이미지 자체를 배포하는 대신 이미지를 생성하는 방법을 기록해 놓은 Dockerfile 을 배포 할 수도 있음
Dockerfile 작성
명령어
FROM: 생성할 이미지의 베이스 이미지
- 사용하려는 이미지가 로컬에 존재하지 않을 경우 자동으로 pull 함
MAINTAINER: 이미지를 생성한 개발자의 정보를 나타냄
- 근데 1.13.0 버전이후로 deprecated 됨
LABEL: 이미지에 메타데이터를 추가 함 “키=값" 형태로 저장되며 이후 docker inspect 명령어로 이미지의 정보를 확인 할 수 있음
RUN 이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행함
ADD: 로컬에 있는 파일을 이미지에 추가함
WORKDIR: 명령어를 실행할 디렉터리를 나타냄
- CD 랑 같다고 생각하면 이해하기 쉬움
EXPOSE: 이미지에서 노출할 포트를 설정함
- 반드시 호스트의 포트와 바인딩 되는 것은 아님
- run 명령어에서 -P플래그를 사용해 컨테이너의 포트를 호스트에 퍼블리시 할 수 있음
CMD: 컨테이너가 시작 할 때 실행할 명령어를 설정함
- Docker 파일에서 단 한번만 사용 할 수 있음
- 하나의 터미널을 차지하는 프로세스가 실행되었을 때 호스트는 -d 옵션을 사용해야함
작성 예시
FROM ubuntu:14.04
LABEL maintainer "asdf"
LABEL purpose="practice"
RUN apt-get update
RUN apt-get install apache2 -y
ADD egg.html /var/www/html
WORKDIR /var/www/html
RUN ["/bin/bash", "-c", "echo hello > test2.html"]
EXPOSE 80
CMD apachectl -DFOREGROUND
이미지 생성
docker build -t egg:0.0 ./
- -t: 생성될 이미지의 이름을 설정함
- 사용하지 않으면 16진수의 형태로 이미지가 저장되므로 가급적이면 사용하는 것이 좋음
- 명령어의 끝에는 Dockerfile 이 저장된 경로를 입력함
컨테이너 실행
docker run -d -P --name eggserver egg:0.0
- -P EXPOSE의 모든 포트를 호스트에 연결하도록 설정
- docker port 명령어로 어디랑 포트포워딩 됐는지 확인가능
docker images --filter "label=purpose=practice"
- 위와 같이 라벨을 통해 이미지목록 필터링 가능
빌드 과정
빌드 컨텍스트
- 이미지를 생성하는 데 필요한 모든 것을 담고 있는 디렉터리를 의미함
- Dockerfile이 위치한 디렉터리임
- 컨텍스트는 build 명령어의 맨 마지막에 지정된 위치에 있는 파일을 전부 포함함
- 따라서 Dockerfile이 위치한 곳에는 이미지 빌드에 필요한 파일만 있는 것이 바람직함
- 불필요한 파일이 포함되면 빌드 속도가 느려지고 호스트가 메모리를 지나치게 점유 할 수 있음
- 이를 방지하기 위해 .gitignore 와 유사한 .dockerignore 파일을 작성할 수 있음
- 해당 파일에 명시된 이름의 파일을 컨텍스트에서 제외함
- 이를 방지하기 위해 .gitignore 와 유사한 .dockerignore 파일을 작성할 수 있음
dockerignore 예시
# nano .dockerignore
test2.html
*.html
*/*.html
test.htm? ex) test.htmb, test.html, .... etc
컨테이너 생성과 커밋
- 이미지로 만드는 과정이 하나의 컨테이너에서 일어나는 것이 아님
- ADD, RUN 등의 명령어가 실행될 때 마다 새로운 컨테이너가 하나씩 생성되며 이를 이미지로 커밋함
- 이전 Step 이미지 기반으로 생성
- 이미지의 빌드가 완료되면 Dockerfile 의 명령어 줄 수 만큼의 레이어가 존재하게 됨
캐시를 이용한 이미지 빌드
- 이전에 빌드할 때 사용한 이미지 레이어는 캐시로 저장한 다음
- 다음에 동일한 이미지 레이어를 사용하는 빌드가 있을 경우 캐시를 활용함
예시
# nano Dockerfile2
FROM ubuntu:14.04
LABEL maintainer "chobe1 <chobe1@naver.com>"
RUN apt-get update
캐시를 사용하고 싶지 않은 경우
- git clone 등의 명령어를 사용해 빌드 할 경우
- 이전의 이미지 레이어만 가져오기때문에 새로운 코드를 반영할 수 없음
- build 명령어에 —no-cache 옵션을 추가해서 해결 할 수 있음
docker build --no-cache -t egg:0.0 ./
- 또는 Dockerfile에 일부 내용을 추가해서 사용
docker build --cache-from nginx -t egg:0.0
멀티 스테이지를 이용한 Dockerfile 빌드
- 일반적으로 애플리케이션을 빌드 할 경우 다량의 의존성 패키지와 라이브러리가 필요함
- Dockerfile 을 통해 빌드 할 때 단순한 기능을 제공하는 애플리케이션도 용량이 커질 수 있음
- 이런 문제점을 여러개의 이미지를 사용해서 해결 할 수 있음
작성예시
FROM golang
ADD main.go /root
WORKDIR /root
RUN go build -o /root/mainApp /root/main.go
FROM alpine:latest
WORKDIR /root
# /root/mainApp 을 alpine:latest 이미지에 복사 from=0 첫번째 FROM 에서 빌드된 이미지의 최종상태
COPY --from=0 /root/mainApp .
CMD ["./mainApp"]
# 특정 단계의 이미지에 별도의 이름을 정의해 사용하는 경우
FROM golang as builder
ADD main.go /root
WORKDIR /root
RUN go build -o /root/mainApp /root/main.go
FROM alpine:latest
WORKDIR /root
COPY --from=builder /root/mainApp .
CMD ["./mainApp"]
'도커' 카테고리의 다른 글
[도커] - 개요 (0) | 2024.02.18 |
---|---|
[도커] - 도커 볼륨 (0) | 2024.01.16 |