DevOps/Docker

[Docker] 도커 이미지 - Dockerfile 개념 및 작성법

seunghwaan 2023. 1. 30. 15:43
반응형

이번 포스트에서는 Dockerfile의 개념과 작성법에 대해 정리하겠습니다.

Dockerfile 사용 유무에 따른 이미지를 생성하는 방법

개발한 어플리케이션을 컨테이너화할 때 생성하는 방법은 아래와 같습니다.

1. 아무것도 존재하지 않는 이미지(ex. 우분투, centOS)로 컨테이너를 생성.

2. 어플리케이션을 위한 환경을 설치하고 소스코드 등을 복사해 잘 동작하는 것을 확인.

3. 컨테이너를 이미지로 커밋(commit)

 

 

컨테이너로 이미지를 생성하는 방법

이 방법을 사용하면 어플리케이션이 동작하는 환경을 구성하기 위해 일일이 수작업으로 패키지를 설치하고 소스코드를 깃(Git)에서 클론하거나 호스트에서 복사해야 합니다. 물론 직접 컨테이너에서 어플리케이션을 구동해보고 이미지로 커밋하기 때문에 이미지의 동작을 보장할 수 있다는 점도 있습니다.

 

Dockerfile로 이미지를 생성하는 방법

도커는 위와 같은 일련의 과정을 손쉽게 기록하고 수행할 수 있는 docker build 명령어를 제공합니다. 완성된 이미지를 생성하기 위해 컨테이너에 설치해야 하는 패키지, 추가해야 하는 소스코드, 실행해야 하는 명령어와 쉘 스크립트 등을 하나의 파일에 기록해두면, 도커는 이 파일을 읽어서 컨테이너에서 작업을 수행한 뒤 이미지로 만듭니다.

 

이러한 작업을 기록한 파일의 이름을 Dockerfile이라고 하며, 빌드 명령어는 Dockerfile을 읽어서 이미지를 생성합니다.

Dockerfile을 사용하면 직접 컨테이너를 생성하고 이미지로 커밋해야 하는 번거러움을 덜어줄 뿐만 아니라 깃과 같은 개발도구를 통해 어플리케이션의 빌드 및 배포를 자동화할 수 있습니다.

 

Dockerfile은 어플리케이션을 개발하는 용도 외에도 여러 목적으로 사용할 수 있습니다.

생성한 이미지를 도커 허브(Docker Hub) 등을 통해 배포할 때, 이미지 자체를 배포하는 대신 이미지를 생성하는 방법을 기록해 놓은 Dockerfile을 배포할 수 있습니다. 특히, 배포되는 이미지를 신뢰할 수 없거나 직접 이미지를 생성해서 사용하고 싶다면 도커 허브에 올려져있는 Dockerfile로 빌드하는 것도 하나의 방법이 됩니다.

 

물론, '컨테이너에서 작업을 마치고 이미지로 커밋하면 되지 않나?'라는 의문점이 생길 수도 있지만, 어플리케이션을 컨테이너화하기 위한 장기적인 시점에서 보았을 때 Dockerfile을 작성하는 것은 이미지를 생성하는 방법을 기록하는 것 뿐만 아니라 이미지의 빌드, 배포 측면에서도 매우 유리합니다. 왜냐하면, 어플리케이션에 필요한 패키지 설치 등을 명확히 할 수 있고, 이미지 생성을 자동화할 수 있으며, 쉽게 배포할 수 있기 때문입니다.

 

Dockerfile 명령어

DockerFile의 기본적인 명령어를 정리하겠습니다.

Dockerfile 작성법이나 명령어에 대해 더 자세히 알고싶다면 도커 공식 레퍼런스를 참고하시면 될 것 같습니다.

 

FROM -> 생성할 이미지의 베이스가 될 이미지를 결정하는 명령어입니다. 모든 Dockerfile은 반드시 FROM 지시어를 한 번 이상 입력해야 하며 이 FROM 지시어를 시작으로 Dockerfile을 작성합니다. 이미지 이름의 포맷은 docker run에서 사용하는 이미지 이름과 동일합니다. 만약, 사용하려는 이미지가 도커 엔진에 없다면 자동으로 도커 허브에서 pull을 시도합니다.

 

LABEL -> 이미지의 메타데이터를 설정하는 명령어입니다. 메타데이터는 '키=값'의 형태로 저장되며, 여러 개의 메타데이터가 저장될 수 있습니다. 추가된 메타데이터는 docker inspect 명령어로 확인할 수 있습니다. 이미지의 메타데이터는 기본적으로 optional이기 때문에 사용하지 않아도 됩니다.

 

WORKDIR -> 명령어를 실행할 디렉토리를 지정하는 명령어입니다. 리눅스에서 cd 명령어와 동일합니다. (Set working directory) 만약, WORKDIR /var/seunghwan 를 실행하고 나서 RUN touch test를 실행하면 /var/seunghwan/ 디렉토리에 있는 test 파일이 생성됩니다.

 

EXPOSE -> Dockerfile의 빌드로 생성된 이미지에서 노출할 포트를 지정하는 명령어입니다. 그러나 EXPOSE를 설정한 이미지를 기반으로 컨테이너를 생성한다고 해서 이 포트가 호스트의 포트와 바인딩하는 것은 아니며, 단지 해당 이미지를 사용하는 사용자에게 해당 포트를 사용한다고 문서화하는 목적을 가지는 것 뿐 입니다. 만약 publish 하고 싶다면 docker run 명령어에 -p(publish) 옵션으로 포트(ex. 8080)를 지정해 주어야 호스트 운영체제에서 해당 포트를 바인딩 합니다.

 

COPY -> 현재 디렉토리 경로의 모든 파일과 디렉토리를 해당 디렉토리에 디렉토리에다가 모두 복사하는 명령어입니다. COPY 지시어의 형태는 COPY <src> <dest> 형식을 가집니다. src는 호스트 운영체제 경로, dest는 이미지 상에서 경로 입니다.

 

만약, COPY packeage*.json ./ 라고 COPY를 사용했다면 호스트 운영체제의 현재 디렉토리 상에 있는 pacakge로 시작해서 .json으로 끝나는 모든 파일을 복사해서 이미지상의 경로로 현재 디렉토리에다가 전부 복사하는 명령을 실행할 것입니다.

 

RUN -> 이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행합니다. 예를들면, apt update, apt-get instsall apache2 명령어를 지정해주면 아파치 웹 서버가 설치된 이미지가 생성됩니다. 단, Dockerfile을 이미지로 빌드하는 과정에서는 별도의 입력이 불가능하기 때문에 apt-get install apache2 명령어에서 설치할 것인지를 선택하는 Y/N 물음에 대해 Yes로 설정해야 합니다. (ex. apt-get install apache2 -y) 이와 같이, 이미지를 빌드할 때 별도의 입력을 받아야 하는 RUN이 있다면 build 명령어는 이를 오류로 간주하고 빌드를 종료합니다.

 

* RUN에는 두가지 형식이 있습니다.

 

1. RUN <명령어> <command> (쉘 형식으로 작성해야 하며, 쉘에서 실행됩니다. Linux의 기본값은 /bin/sh -c 이고 Windows에서 기본값은 /S /C 입니다.)

 

2. RUN ["실행 가능한 파일", "param1", "param2"] (exec 형식) (이는 JSON 배열의 입력 형식을 따르기 때문에 JSON 형식과 일치해야 합니다. 단, JSON 배열 형태로 Dockerfile의 명령어를 사용하면 쉘을 실행하지 않습니다. 예를 들면, ["echo", "$MY_ENV"]는 $MY_ENV 환경변수를 사용하지 않습니다. 이 형태로 쉘을 사용하려면 ["sh", "-c", "echo $MY_ENV"]와 같이 사용하는 것이 좋습니다.)

 

만약, RUN 명령어에 ["/bin/bash", "echo hello >> test.html"]을 입력하면 /bin/bash 쉘을 이용해 "echo hello >> test.html"을 실행합니다. Dockerfile의 일부 명령어는 RUN 명령어 처럼 배열의 형태로 사용할 수 있습니다.

 

ADD -> 파일을 이미지에 추가합니다.추가하는 파일은 Dockerfile이 위치한 디렉토리인 컨텍스트(Context)에서 가져옵니다. 컨텍스트는 다루지 않았지만 Dockerfile이 위치한 디렉토리라고 이해하면 됩니다.

ADD 명령어는 JSON 배열의 형태로 ["추가할 파일 이름", "컨테이너에 추가될 위치"]와 같이 사용할 수 있습니다. 추가할 파일명은 여러 개를 지정할 수 있으며 배열의 마지막 원소가 컨테이너에 추가될 위치입니다.

 

CMD -> CMD는 해당 이미지로 컨테이너를 실행할 때 어떤 명령어를 수행할 것인지를 결정하는 명령어이며 Dockerfile에서 한 번만 사용할 수 있습니다. Dockerfile에 CMD를 명시함으로써 이미지에 apachetcl -DFOREGROUND라는 커맨드를 내장하면 컨테이너를 생성할 때 별도의 커맨드를 입력하지 않아도 이미지에 내장된 apachectl -DFOREGROUND 커맨드가 적용되어 컨테이너가 시작될 때 자동으로 아파치 웹 서버가 실행될 것 입니다. 그리고 아파치 웹 서버는 하나의 터미널을 차지하는 포그라운드 모드로 실행되기 때문에 -d 옵션을 사용해 detached 모드로 컨테이너를 생성해야 합니다.

즉 CMD는 run 명령어의 이미지 이름 뒤에 입력하는 커맨드와 같은 역할을 하지만 docker run 명령어에서 커맨드 명령줄 인자를 입력하면 Dockerfile에서 사용한 CMD의 명령어는 run의 커맨드로 덮어 쓰입니다. 이와 마찬가지로 ubuntu:focal 이미지에 기본적으로 내장된 커맨드인 /bin/bash 또한 Dockerfile의 CMD에 의해 덮어 쓰입니다.

 

CMD의 입력은 JSON 배열 형태인 ["실행 가능한 파일", "명령줄 인자1", "명령줄 인자2"]의 형태로도 사용할 수 있습니다. 그리고 문자열 형태인 " "로도 사용할 수 있습니다. 또한 CMD는 ENTRYPOINT가 존재한다면 명령어가 아니라 ENTRYPOINT의 명령줄 인자로 사용될 수 있습니다.

 

ENTRYPOINT -> ENTRYPOINT는 도커 컨테이너가 실행할 때 고정적으로 실행되는 스크립트 혹은 명령어입니다.

생략 가능하며, 생략할 경우 커맨드(CMD)에 지정된 명령어로 수행합니다. ENTRYPOINT와 CMD의 차이점은 ENTRYPOINT는 CMD를 인자로 받아 사용할 수 있는 스크립트의 역할을 할 수 있다는 점입니다. 

 

만약, 아래와 같이 사용한다면 top, -b -c 순서로 실행될 것 입니다.

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

Dockerfile로 이미지 빌드하기

앞에서 Dockerfile 명령어들을 알아보았으니 Dockerfile로 이미지를 생성하겠습니다.

 

아래는 노드 JS 이미지를 생성하는 Dockerfile 입니다 .

#
# nodejs-server
#
# build:
#   docker build --force-rm -t nodejs-server .
# run:
#   docker run --rm -it --name nodejs-server nodejs-server
#

FROM node:16
LABEL maintainer="Seunghwan Seo <seosh817@naver.com>"
LABEL description="Seunghwan's Node.js server"

# Create app directory
WORKDIR /app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

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

Dockerfile을 빌드하기 전에 위의 Dockerfile을 간단하게 해석해보면

 

FROM -> 노드 JS 16버전의 이미지를 가져옵니다.

 

WORKDIR -> 명령어를 실행할 위치를 /app/ 디렉토리로 이동합니다.

 

COPY -> 호스트 운영체제의 현재 디렉토리 상에 있는 pacakge로 시작해서 .json으로 끝나는 모든 파일을 복사해서 이미지상의 경로로 현재 디렉토리에다가 전부 복사하는 명령을 실행합니다.

 

RUN -> npm install을 지정해 주었으므로 이미지 상에서 WORKDIR 명령어로 지정해준 현재위치인 /app/ 디렉토리에서 COPY 명령어로 package*.json을 복사 붙여넣고, npm install로 pacakge*.json들을 읽어다가 패키지를 설치할 것입니다.

 

COPY -> COPY는 형태는 COPY 에서 src는 호스트 운영체제 경로, dest는 이미지 상에서 경로 이므로,

위의 Dockerfile에서 COPY . . 명령어는 호스트 운영체제 상의 모든 파일과 디렉토리를 이미지 상의 /app/ 위치에 모두 복사해라 라고 해석하면 됩니다. 즉, COPY . . 을 한 이유는 소스코드의 변경사항을 이 레이어 뒤에 실행하기 위함입니다.

 

EXPOSE -> 8080 포트를 사용하겠다고 expose 합니다.

 

CMD -> 쉘에서 'node server.js' 명령어를 실행합니다.

 

이제 Dockerfile로 이미지를 생성하겠습니다.

아래 명령어를 입력해줍니다.

$ docker build --force-rm -t nodejs-server:1.0.0 .

-t 옵션 -> 생성될 이미지의 이름을 설정합니다. 위 명령을 실행하면 nodejs-server:1.0.0 이라는 이름의 이미지가 생성됩니다. -t 옵션을 사용하지 않으면 16진수 형태의 이름으로 이미지가 저장되므로 가급적이면 -t 옵션을 사용하는 것이 좋습니다.

docker build 명령어 끝에는 Dockerfile이 저장된 경로를 입력합니다. 일반적으로는 로컬에 저장된 Dockerfile을 사용하지만 외부 URL로부터 Dockerfile의 내용을 가져와 빌드할 수도 있습니다. 이 예시에서는 로컬에 Dockerfile을 저장했으므로 .(/)(현재 디렉토리)를 입력했습니다.

--force-rm 옵션 -> 중간중간에 생성되는 임시 컨테이너를 제거합니다.

 

Dockerfile build

빌드를 시작하면 위와 같은 내용이 출력되며 nodejs-server:1.0.0이라는 이름의 이미지가 생성됩니다. 컨테이너가 실행될 때 CMD에서 'node server.js' 명령어로 노드 JS 서버를 실행하도록 설정했기 때문에 컨테이너를 실행하면 노드 JS 서버가 실행됩니다.

 

이제 다음 명령어를 입력해서 생성된 이미지로 컨테이너를 실행 해보겠습니다.

$ docker run -d -P --name my_nodejs_server nodejs-server:1.0.0

-P 옵션 -> 이미지에 설정된 EXPOSE의 모든 포트를 호스트에 연결하도록 설정합니다. 위 예시에서는 Dockerfile에서 EXPOSE를 80번으로 설정했으며 이는 이미지에 '컨테이너의 80번 포트를 사용한다'는 것을 의미합니다. 즉, 이미지를 생성하기 위한 Dockerfile을 작성하는 개발자로서는 EXPOSE를 이용해 이미지가 실제로 사용될 때 어떤 포트가 사용돼야 하는지 명시할 수 있으며, 이미지를 사용하는 입장에서는 컨테이너의 어플리케이션이 컨테이너 내부에서 어떤 포트를 사용하는지 알 수 있게 됩니다. -P 옵션은 EXPOSE로 노출된 포트를 호스트에서 사용 가능한 포트에 차례로 연결하므로 이 컨테이너가 호스트의 어떤 포트와 연결됐는지 확인할 필요가 있습니다.

 

docker ps 또는 docker port 명령어로 컨테이너와 연결된 호스트의 포트를 확인할 수 있으며, 호스트의 IP와 이 포트로 컨테이너의 웹 서버에 접속할 수 있습니다. ([호스트 IP]:[포트]/[파일명])

빌드 과정 살펴보기

docker build 명령어를 입력했을때 여러 내용이 출력되었는데 내용 중 대부분은 Dockerfile의 RUN 명령어를 실행해서 컨테이너 내부에서 발생한 표준 출력이지만 이미지를 생성하는 부분은 자세히 살펴볼 필요가 있습니다.

빌드 컨텍스트란?

이미지 빌드를 시작하면 도커는 가장 먼저 빌드 컨텍스트(build context)를 읽어 들입니다. 빌드 컨텍스트는 이미지를 생성하는 데 필요한 각종 파일, 소스코드, 메타데이터 등을 담고 있는 디렉토리를 의미하며, Dockerfile이 위치한 디렉토리가 빌드 컨텍스트가 됩니다.

 

컨테이너 내부 접속

컨테이너 내부에 접속하면 빌드 컨텍스트를 확인할 수 있습니다.

빌드 컨텍스트는 Dockerfile에서 빌드될 이미지에 파일을 추가할 때 사용됩니다. Dockerfile에서 이미지에 파일을 추가하는 방법은 ADD, COPY 등의 명령어가 있습니다. 이 명령어들은 빌드 컨텍스트의 파일을 이미지에 추가합니다. 위 예제에서는 WORKDIR 명령어로 빌드 경로를 /app으로 지정함으로써 빌드 컨텍스트에서 package*.json 파일을 읽어들여 노드 JS 서버를 빌드할 수 있습니다.

 

컨텍스트에 대한 정보는 이미지를 빌드할 때 출력된 내용 중 맨 위에 위치합니다.

 

컨텍스트는 docker build 명령어의 맨 마지막에 지정된 위치에 있는 파일을 전부 포함합니다. 깃(Git)과 같은 외부 URL에서 Dockerfile을 읽어 들인다면 해당 저장소(Repository)에 있는 파일과 서브 모듈을 포함합니다. 따라서 Dockerfile이 위치한 곳에는 이미지 빌드에 필요한 파일만 있는 것이 바람직하며, 루트 디렉토리(/)와 같은 곳에서 이미지를 빌드하지 않도록 주의해야 합니다. 컨텍스트는 단순 파일뿐 아니라 하위 디렉토리도 전부 포함하게 되므로 빌드에 불필요한 파일이 포함된다면 빌드 속도가 느려질뿐더러 호스트의 메모리를 지나치게 점유할 수도 있습니다.

 

.dockerignore 파일

.dockerignore 파일은 빌드 컨텍스트에 불필요한 파일이 포함 되는 것을 방지하기 위해 깃에서 사용하는 .gitignore와 유사한 기능을 사용할 수 있으며 .gitgnore파일과 문법이 동일합니다. 즉, .dockerignore라는 파일을 작성하면 빌드 시에 이 파일에 명시된 이름의 파일을 컨텍스트에서 제외합니다. .dockerignore 파일을 컨텍스트의 최상위 경로, 즉 build 명령어에서 맨 마지막에 오는 경로인 Dockerfile이 위치한 경로와 같은 곳에 위치해야 합니다.

 

아래는 .dockerignore 파일의 예제입니다.

test.html
*.html
*/*.html
test.htm?

컨텍스트에서 제외할 파일의 경로는 Dockerfile이 존재하는 경로를 기준으로 합니다. 예를 들어, build 명령어에서 설정한 경로가 현재 디렉토리이고 /home/seosh817 이라면 *.html은 /home/seosh817/*.html에 해당하는 모든 파일을 뜻합니다. 마찬가지로 */*.html은 /home/seosh817/*/*.html에 해당하는 파일을 제외한다는 의미입니다. 즉, */으로 구분되는 디렉토리는 한 디렉토리 레벨을 뜻하며, 중간에 어떤 디렉토리가 오든 상관없습니다.

 

test.html?은 test.htm을 접두어로 두고 "?" 자리에 임의의 1자리의 문자가 들어가는 파일을 제외합니다. 즉, .dockerignore에 test.html?을 지정하면 test.htma, test.htmb ... 등이 컨텍스트에서 제외됩니다.

 

만약, 제외 목록에는 해당하지만 특수한 파일만 포함되도록 설정하고 싶다면 "!"를 사용합니다. "!"는 특정 파일을 제외하지 않음을 뜻합니다. 아래의 예시는 확장자가 .html인 파일을 모두 제외하지만 test로 시작하는 html 파일을 컨텍스트에서 제외하지 않습니다.

*.html
!test*.html

Dockerfile을 이용한 컨테이너의 생성과 커밋

build 명령어는 Dockerfile에 기록된 대로 컨테이너를 실행한 뒤 완성된 이미지를 만들어 냅니다. 그렇지만 이미지로 만드는 과정이 하나의 컨테이너에서 일어나는 것은 아닙니다. 이미지를 빌드할 때 나오는 아래와 같은 "Removing intermediate container [container id]" 출력 결과를 통해 이를 어느정도 짐작할 수 있습니다.

 

docker build

각 Step은 Dockerfile에 기록된 명령어에 해당합니다. FROM, RUN, WORKDIR 등의 명령어가 실행될 때 마다 새로운 컨테이너가 하나씩 생성되며 이를 이미지로 커밋합니다. 즉, Dockerfile에서 명령어 한 줄이 실행될 때마다 이전 Step에서 생성된 이미지에 의해 새로운 컨테이너가 생성되며, Dockerfile에 적힌 명령어를 수행하고 다시 새로운 이미지 레이어로 저장됩니다.

 

이미지 빌드 시 일어나는 컨테이너 생성과 커밋

따라서 이미지의 빌드가 완료되면 Dockerfile의 명령어 줄 수만큼의 레이어가 존재하게 되며, 중간에 컨테이너도 같은 수만큼 생성되고 삭제됩니다. 위 출력 결과에서 Removing intermediate container ...는 중간에 이미지 레이어를 생성하기 위해 임시로 생성된 컨테이너를 삭제하는 것이고 삭제되기 전 출력되는 ID는 커밋된 이미지 레이어를 의미합니다.

 

캐시를 이용한 이미지 빌드

한 번 이미지 빌드를 마치고 난 뒤 다시 같은 빌드를 진행하면 이전의 이미지 빌드에서 사용했던 캐시를 사용합니다. 아래의 내용을 파일로 저장하고 다시 이미지를 빌드해 보겠습니다. 아래 Dockerfile은 위에서 빌드했던 이미지에서 몇개의 명령어를 지웠습니다.

FROM node:16
LABEL maintainer="Seunghwan Seo <seosh817@naver.com>"
LABEL description="Seunghwan's Node.js server"
WORKDIR /app
COPY package*.json ./
RUN npm update
RUN npm install
COPY . .

Dockerfile의 이름을 Dockerfile2로 저장했습니다. docker build 명령어의 -f(-file) 옵션으로 Dockerfile의 이름을 지정할 수 있습니다. 그래서, docker build 명령어를 docker build -f Dockerfile2 -t cache:0.0 ./ 로 입력해 Dockerfile2를 빌드해주겠습니다.

$ docker build -f Dockerfile2 -t cache:0.0 ./

Using cache라는 출력 내용과 함께 별도의 빌드 과정이 진행되지 않고 바로 이미지가 생성 되었습니다. 이전에 빌드했던 Dockerfile에 같은 내용이 있다면 build 명령어는 이를 새로 빌드하지 않고 같은 명렁어 줄까지 이전에 사용한 이미지 레이어를 활용해 이미지를 생성합니다. 이는 같은 명령를 여러 번 실행해야 하는 여러 개의 이미지를 빌드하거나 빌드 도중 Dockerfile의 문법과 기타 오류가 발생했을 때 불필요하게 다시 명령어를 실행하지 않게 합니다.

 

* 만약 이미지 빌드 중 오류가 발생했다면?

이미지 빌드 중 오류가 발생했을 때는 build 명령어가 중지되고, 이미지 레이어 생성을 위해 마지막으로 생성된 임시 컨테이너가 삭제되지 않은 채로 남게됩니다. 또한 이미지의 빌드가 완전하지 않기 때문에 -t 옵션의 값으로 지정된 이미지의 이름이 아닌 <none>:<none>으로 이미지가 생성됩니다. 이러한 이미지를 삭제하기 위해서는 docker rmi [image id] 명령어로 이미지를 삭제하면 됩니다.

 

 

캐시가 불필요한 경우

그러나 때로는, 오히려 캐시 기능이 필요하지 않을 때도 있습니다.

위 그림과 같이 깃허브 같은 소스코드 저장소에서 git clone 등의 명령어를 사용해 빌드할 때가 여기에 해당합니다.

Dockerfile에 RUN git clone ... 을 사용해 이미지를 빌드했다면 RUN에 대한 이미지 레이어를 계속 캐시로 사용하기 때문에 실제 깃 저장소에서 리비전 관리가 이루어져도 매번 빌드를 할 때마다 고정된 소스코드가 clone 될 것입니다.

 

이 경우 캐시를 사용하지 않으려면 buile 명령어에 --no-cahe 옵션을 추가합니다. --no-cahe 옵션을 사용하면 기존 빌드에 사용된 캐시를 사용하지 않고 Dockerfile을 처음부터 다시 이미지 레이어로서 빌드합니다.

 

$ docker build --no-cache -f Dockerfile2 -t cache:0.0 ./

또는 캐시로 사용할 이미지를 직접 지정할 수도 있습니다.

 

--cache-from 옵션 -> 특정 Dockerfile을 확장해서 사용한다면 기존의 Dockerfile로 빌드한 이미지를 빌드 캐시로 사용할 수 있습니다. 예를 들면, 도커 허브의 nginx 공식 저장소에서 nginx:latest 이미지를 빌드하는 Dockerfile에 일부 내용을 추가해 사용한다면 로컬의 nginx:latest 이미지를 캐시로 사용할 수 있습니다.

$ docker build --cache-from nginx my-extend_nginx:0.0 .

 

 

반응형