# Dockerfile 표준화 작업 진행
Dockerfile 작성 레퍼런스 사이트 : https://docs.docker.com/engine/reference/builder/
1. Dockerfile 작성 시 기본 명령어는 아래와 같다.
명령설명
FROM | 베이스 이미지 지정 |
RUN | 명령 실행 |
CMD | 컨테이너 실행 명령 |
LABEL | 라벨 설정 |
EXPOSE | 포트 익스포트 |
ENV | 환경변수 |
ADD | 파일/디렉토리 추가 |
COPY | 파일 복사 |
ENTRYPOINT | 컨테이너 실행 명령 |
VOLUME | 볼륨 마운트 |
USER | 사용자 지정 |
WORKDIR | 작업 디렉토리 |
ARG | Dockerfile 안의 변수 |
ONBUILD | 빌드 완료 후 실행되는 명령 |
STOPSIGNAL | 시스템 콜 시그널 설정 |
HEALTHCHECK | 컨테이너의 헬스 체크 |
SHELL | 기본 쉘 설정 |
2. Dockerfile에서 주석 사용방법
# 이것은 첫번째 주석입니다
명령 인수
# 이것은 두번째 주석입니다
명령 인수 # 이것도 주석입니다
3. Dockerfile 작성
Dockerfile에는 Docker 컨테이너를 어떤 Docker 이미지로부터 생성할지 정보를 반드시 기술 해야한다.
이 이미지를 베이스 이미지라고 할 수 있다.
FROM 명령 (베이스 이미지 정보를 기술)
FROM [이미지명]
FROM [이미지명]:[태그명]
FROM [이미지명]:[다이제스트]
Docker image란 컴퓨터의 CD와도 같다고 볼 수 있다. 그래서 Docker image는 수정 할 수 없다. 단 이미지에 추가로 무언가를 추가 할 수는 있다.
Docker image는 레이어 구조로 되어 있고, 즉 기본이 되는 레이어가 존재하고, 그 기본 레이어에 계속해서 추가하는 방식으로 이미지를 생성 한다.
Docker image를 조회하는 명령어는 아래와 같다.
docker inspect {이미지 이름}
4. zulu-open-zdk:13을 베이스 이미지로 한 Dockerfile
태그명을 입력하지 않으면 베이스 이미지의 최신 버전(latest)이 적용된다.
이미지명이나 태그명은 작성자가 임의의 값을 붙일 수 있으므로 Dockerfile을 수정해도 똑같은 이름으로 몇 번이든 이미지를 만들 수 있다.
# 베이스 이미지 설정
FROM azul/zulu-openjdk:13
다이제스트 확인
다이제스트는 Docker Hub에 업로드하면 자동으로 부여되는 식별자를 말함
이 다이제스트는 고유한 식별자이기 때문에 이미지를 고유하게 지정할 수 있음
docker image ls --digests azul/zulu-openjdk
다이제스트를 지정한 Dockerfile
FROM azul/zulu-openjdk@sha256:12945255963826437ca7c52f2ffe45b6862b24b4b73dfb74af05d461607f75ac
Dockerfile의 빌드와 이미지 레이어
Dockerfile로 부터 이미지를 생성하려면 docker build 명령을 사용한다.
docker build 명령의 서식
docker build -t [생성할 이미지명] : [태그명] [Dockerfile의 위치]
docker build 명령의 실행 예
Dockerfile로 부터 sample 이라는 이미지를 작성 태그명: 1.0, Dockerfile의 저장 위치를 절대 경로로 지정
/home/docker/sample 물론 상대경로로 지정할 수도 있다.
docker build -t sample:1.0 /home/docker/sample
이미지 확인하는 명령어는 아래와 같다.
docker image ls
새로운 이미지의 작성 예시 → 생성할 이름은 다르지만 동일한 이미지가 생성된다.
docker build -t sample:2.0 /home/docker/sample
파일명을 지정한 docker build 명령 실행
현재 디렉토리에 있는 Dockerfile.base라는 이름의 파일을 -f 옵션으로 지정하여 build
파일명이 Dockerfile 이외의 이름인 경우는 Docker Hub에서 이미지의 자동 생성 기능을 사용할 수 없음
docker build -t sample -f Dockerfile.base .
표준 입력에서의 빌드
표준 입력을 경유하여 Dockerfile을 지정하여 빌드를 할 수도 있음
표준 입력의 내용은 Dockerfile의 내용을 docker build 명령의 인수로 전달하므로 -(하이픈)을 지정한다.
docker build - < Dockerfile
압축 아카이브를 활용하여 빌드를 수행 할 수도 있다.
표준 입력에서의 빌드: 빌드에 필요한 파일을 포함시킬 수 없기 때문에 Dockerfile과 빌드에 필요한 파일을 tar로 모아두고 표준 입력에서 지정함
docker build - < docker.tar.gz
중간 이미지의 재이용
Docker는 이미지를 빌드할 때 자동으로 중간 이미지를 생성하고, 해당 이미지를 다른 이름으로 빌드할 때 중간 이미지를 내부적으로 재이용함으로써 빌드를 고속으로 수행함, 이미지를 재이용하고 있을 때는 빌드 로그에 'Using cache' 라고 표시된다.
이 캐시를 이용하고 싶지 않을 경우는 docker build 명령에서 --no-cache 옵션을 지정하여 빌드를 수행 한다.
Docker 이미지의 레이어 구조
4개의 명령을 갖고 있는 Dockerfile의 예
Dockerfile과 동일한 디렉토리에 임의의 'index.html' 이라는 이름의 파일을 생성하고 docker build 명령으로 이미지를 작성하면
각 레이어마다 이미지가 생성되고 네개의 이미지가 생성된다.
# STEP:1 Ubuntu (베이스 이미지)
FROM ubuntu:latest
# STEP:2 Nginx 설치
RUN apt-get update && apt-get install -y -q nginx
# STEP:3 파일 복사
COPY index.html /usr/share/nginx/html/
# STEP:4 Nginx 시작
CMD ["nginx", "-g", "daemon off;"]
멀티스테이지 빌드를 사용한 Dockerfile 만들기
Sample 앱
git clone https://github.com/asashiho/dockertext2
cd dockertext2/chap05/multi-stage/
Dockerfile 작성 예시
- 개발 환경용 Docker 이미지
- 개발용 언어 Go 버전 1.8.4를 베이스 이미지로 작성 후 builder 라는 별명을 붙임
# 1. Build Image
FROM golang:1.8.4-jessie AS builder
- 개발에 필요한 버전을 설치하여 로컬 환경에 있는 소스코드를 컨테이너 안으로 복사함
# Install dependencies
WORKDIR /go/src/github.com/asashiho/greet
RUN go get -d -v github.com/urfave/cli
- 소스코드를 go build 명령으로 빌드하여 greet 라는 이름의 실행 가능 바이너리 파일을 작성
# build modules
COPY main.go .
RUN GOOS=linux go build -a -o greet .
- 제품 환경용 Docker 이미지
- 베이스 이미지는 busybox(기본적인 Linux 명령들을 하나의 파일로 모아 놓은 것, 최소한으로 필요한 Linux 쉘 환경 제공)를 사용
# 2. Production Image
FROM busybox
WORKDIR /opt/greet/bin
- 개발용 환경의 Docker 이미지로 빌드한 greet라는 이름의 실행 가능 바이너리 파일을 제품 환경용 Docker 이미지로 복사
--from 옵션을 사용하여 builder 라는 이름의 이미지로 부터 복사 한다는 것을 선언
# Deploy modules
COPY --from=builder /go/src/github.com/asashiho/greet/ .
- 복사한 실행 가능 바이너리 파일을 실행하는 명령 작성
ENTRYPOINT ["./greet"]
전체 dockerfile 코드
# 1. Build Image
FROM golang:1.8.4-jessie AS builder
# Install dependencies
WORKDIR /go/src/github.com/asashiho/greet
RUN go get -d -v github.com/urfave/cli
# build modules
COPY main.go .
RUN GOOS=linux go build -a -o greet .
# ------------------------------------------
# 2. Production Image
FROM busybox
WORKDIR /opt/greet/bin
# Deploy modules
COPY --from=builder /go/src/github.com/asashiho/greet/ .
ENTRYPOINT ["./greet"]
생성한 이미지 확인
개발 환경용 이미지인 goland:1.8.4-jessie는 803MB 지만 제품 환경용 greet 는 겨우 6.02MB으로 빌드 되었다.
제품 환경용 베이스 이미지인 busybox 의 1.22MB에 애플리케이션의 실행에 필요한 모듈만을 추가한 정도임
제품 환경에서는 부하에 따라 작동하는 컨테이너의 수가 바뀜
가능한 한 용량이 적은 이미지를 사용하면 시스템 전체의 컴퓨팅 리소스를 효율적으로 활용할 수 있음
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
greet latest 56b7008ab820 41 seconds ago 6.02MB
busybox latest 83aa35aa1c79 6 days ago 1.22MB
golang 1.13 3a7408f53f79 2 weeks ago 803MB
Docker 컨테이너 실행
Sample 앱은 인수를 사용하여 인사를 반환하는 간단한 커맨드라인 툴이지만
제품 환경용으로 만든 저용량 이미지인 greet만으로 작동하고 있다는 것을 알 수 있음
docker container run -it --rm greet asa
Hello asa
docker container run -it --rm greet --lang=es asa
Hola asa
실행중인 docker 프로세스 확인
sudo docker ps -a
:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
184bf0f54ed2 notice-board "java -jar /app.jar" 9 hours ago Up 9 hours 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp notice-board
'Docker > Docker (도커)' 카테고리의 다른 글
docker image 이름 변경하기 (0) | 2023.07.06 |
---|---|
docker tail -f 명령어를 활용하여 로그 확인하기 (0) | 2022.05.31 |
Dockerfile 내용 정리 대상 (0) | 2022.03.21 |
Docker image 찾는 방법 (0) | 2021.12.23 |
the input device is not a TTY. If you are using mintty, try prefixing the command with 'winpty' 에러 발생 시 (0) | 2021.12.13 |