docker build 과정

2020. 2. 2. 18:31devops/docker

docker build 과정 

docker build -t mybuild:0.0 ./

이전에 우리가 build를 할 때 위와 같은 명령어를 사용했다. 우선 docker는 위와 같은 명령어로 build를 시작하면 build context를 읽어 들입니다. build context는 이미지를 생성하는 데 필요한 각종 파일, 소스코드, 메타데이터 등을  담고 있는 디렉터리를 의미합니다. build 명령어 제일 마지막에 폴더위치 이다. 

 

빌드 컨텍스트는 이미지에 파일을 추가할 때 사용됩니다. Dockerfile에서 이미지에 파일을 추가하는 방법은 ADD, COPY 등이 있습니다. 이 명령어들은 빌드 컨텍스트의 파일을 이미지에 추가합니다. 그래서 위의 경우에는 현재 폴더에 위치한 파일 test.html은 이미지의 폴더 www/html에 추가했습니다. 

 

깃과 같은 외부 URL에서 Dockerfile을 읽어 들인다면 해당 저장소에 있는 파일과 서브 모듈을 포함합니다. 따라서 Dockerfile이 위치한 곳에는 이미지 빌드에 필요한 파일만 있는 것이 바람직하며 루트 디렉터리(/)와 같은 곳에서 이미지를 빌드하지 않는 것이 중요합니다. 컨텍스트는 파일뿐 아니라 하위 디렉터리도 전부 포함하게 되므로 빌드에 불피요한 파일이 포함된다면 빌드 속도가 느려지고 메모리를 많이 잡아 먹습니다. 

 

이를 방지하기 위해 .dockerignore라는 파일을 작성하면 빌드시 파일에 명시된 이름의 파일을 build context 폴더에서 제외합니다. 

.dockerignore는 build 명령어에서 제일 마지막에 오는 곳에 위치해야합니다. 

 

.dockerignore는 아래와 같이 적을 수 있다. 

test2.html
*.html
*/*.html
test.htm?
!test.html

만약 현재 폴더의 위치가 /hoony/home이면 이 위치가 base가 되어 뒤의 파일들을 제외한다. 

 

hoony/home/test2.html

hoony/home/*.html: .html이 포함된 모든 파일

hoony/home/*/*.html home의 모든 자식 폴더 포함

hoony/home/test.htm? ?는 모든 html, htma, htm뒤에 붙는 모든 것이된다. 

hoony/home/!test.html !는 이 파일이 제외되는 것이 아닌 무조건 포함되어야 하는 것이다. 

 

build 명령어를 사용하여 각 step 별로 실행된다. Dockerfile마다 한줄한줄 마다 각 step으로 보여줍니다. 

위와 같이 각 step으로 진행한다음 각 stepquffh 새로운 layer를 추가하여 새로운 이미지 layer로 저장됩니다. 그래서 Dockerfile의 명령어 수만큼 레이어가 존재하게됩니다. 그리고 해당 명령어 수만큼 컨테이너가 생성된다. 이 컨테이너들은 이미지 레이어를 생성하기 위해 임시 컨테이너를 생성하게 삭제합니다. 그리고 Removing되기전 출력되는 ID는 커밋된 레이어를 의미합니다. 

 

이전 도커파일의 FROM, ADD를 제외한 명령어 줄 6개의 Layer가 쌓였다. 

 

캐시를 이용한 이미지 빌드 

한번 이미지를 빌드를 마치고 난 뒤 다시 같은 빌드를 진행하면 이전의 빌드에서 사용했던 캐시를 사용합니다. 다른 Dockerfile을 만들어서 다시 진행해봅시다. 

 

Dockerfile2

FROM ubuntu:14.04

LABEL maintainer "dl57934<dl57934@gmail.com>"
LABEL "purpose"="practice"
RUN apt-get update

이미지 만들기

docker build -f Dockerfile2 -t testCache ./

-f 옵션은 원래 이미지를 만들때는 지정한 폴더안에 Dockerfile을 찾아서 build하지만 -f 옵션을 통해 build할 도커파일을 지정할 수 있습니다.

이전과 다르게 using Cache log가 나옵니다. 이는 Docker에서 이전에 build했던 dockerfile에 동일한 명령어가 있으면 새로 빌드하지 않고 같은 명령어 줄까지 이전에 사용한 이미지 레이어를 활용해 이미지를 생성합니다. 

 

하지만 cache가 필요하지 않을 수도 있습니다. 예를 들어 github에서 clone하는 명령어가 있는데 변경사항이 있어 commit, push를 했는데 이전과 동일한 Dockerfile로 다시 build하면 예전 코드가 clone되어 옵니다. 이럴 때는 cache를 사용하지 않는 --no-cache 옵션을 추가하면됩니다. 

docker build --no-cache -t nocachebuildimage

또는 캐시로 사용할 이미지를 직접 지정할 수 있습니다. 기존 Dockerfile을 확장하여 사용한다면 계속해서 cache를 사용하는 것이 좋을 수 있습니다. 

docker build --cache-from nginx -t my_extend_nginx

멀티 스테이지를 이용한 Dockerfile 빌드하기 

일반적으로 애플리케이션을 빌드하려면 많은 의존성 패키지 및 라이브러리를 필요로합니다. 그래서 이미지자체의 용량이 커지거나 최종적으로 실행할 때 불피요한 라이브러리들이 있을 수 있습니다. 이럴 때는 멀티 스테이즈를 활용하여 여러개의 FROM 명령어를 사용하여 최종적으로는 반드시 필요한 실행 파일만 최종 이미지 결과물에 포함시켜 이미지의 용량을 줄일 때 유용합니다.

 

package main
import "fmt"
func main(){
	fmt.Println("hello world")
}

Dockerfile

FROM golang 
ADD mina.go /root
WORKDIR /root
RUN go build -o /root/mainApp /root/main.go
CMD ["./mainApp"]

//build 화
docker build -t go_helloworld .

단순히 hello world를 출력시키는 go 코드가 800mb나된다. 이는 문제가 있습니다....

그래서 이번에는 멀티스테이지를 사용하여 이미지의 용량을 줄여보겠습니다. 이전의 Dockerfile을 수정해보겠습니다. 

FROM golang 
ADD main.go /root
WORKDIR /root
RUN go build -o /root/mainApp /root/main.go

FROM alpine:lastest
WORKDIR /root
COPY --from=0 /root/mainApp .
CMD ["./mainApp"]

docker build -t go_helloworld .

일반적인 Dockerfile과 다르게 2개의 FROM을 통해 2개의 이미지를 적어주었다. 여기서 주의해서 볼 곳은 두번째 FROM에서 /root/mainApp에 존재하는 파일을 .로 이동합니다. 이 때 --from=0은 첫 번째 FROM에서 빌드된 이미지의 최종 상태를 의미합니다. 

 

multistage성공한 이미지

같은 기능을 하지만 위와 같이 용량이 훨씬 줄어든 것을 볼 수 있다. multi-stage를 사용하면 Dockerfile은 두개 이상의 이미지를 사용할 수있게된다. 각 from마다 0, 1, 2등이 붙으며 --from=여기 넣어주면된다. 0, 1, 2,....의 숫자가 싫으면 자기가 지정할 수 있다. 아래와 같이 지정할 수 있다. 

From go as first
--from=first

 

----------------------------------------------------------------------------------------------------------------------

 

살다 살다 이런 날이 오네요.... 블로그에 협찬이 들어왔습니당.

 

 

이름하여 도커 컨테이너 휴지곽!!! 

 

 

상당히 귀엽습니다 ㅎㅎ.. 회사 개발자분들에게 너무 귀엽다며 인싸 템이라고 얘기를 들으니 기분이 좋더라구용 ㅎㅎ. 퀄리티도 상당히 좋았습니다. 옆면 뒷면을 보면 실제 컨테이너와 같은 모습을 하고 있어서 놀랐습니다. 또 조립 자체도 어렵지 않아서 누구나 쉽게 조립할 수 있을 것 같습니다. 하지만 철로된 휴지를 들어주는 부분은 날카로워서 조립하실 때 조심하셔야 할 것 같습니다.

 

 

휴지도 매우 깔끔하게 들어가고 뽑기도 시워서 사용하기 너무 편했어요!!! 

 

 

귀엽우면서 퀄리티도 좋고 사용성이 편해서 매우 추천 드립니다. 구매가 필요하시면 아래 사이트에서 할 수 있습니다!!

https://incatos.shop/surl/P/11

 

협찬 주신 인카토스님 감사합니다!!!

 

'devops > docker' 카테고리의 다른 글

Docker 구조  (0) 2020.02.04
Dockerfile 명령어  (0) 2020.02.04
docker file 작성  (0) 2020.01.31
docker image 배포  (0) 2020.01.31
docker 이미지  (0) 2020.01.31