[참고사이트] – [Docker] Docker 이미지 – Dockerfile 개념 및 작성법 1. Dockerfile 사용 유무에 따른 이미지 생성 방법 개발한 애플리케이션을 컨테이너화할 때 생성하는 방법은 다음과 같습니다. ① 아무것도 존재하지 않는 이미지(ex.Ubuntu, centOS)로 컨테이너를 생성. ② 애플리케이션을 위한 환경을 설치하고 소스 코드 등을 복사하여 잘 동작하는지 확인. ③ 컨테이너를 이미지화하여 커밋[참고 사이트] – [Docker] Docker 이미지 – Dockerfile 개념 및 작성법 1. Dockerfile 사용 유무에 따른 이미지 생성 방법 개발한 애플리케이션을 컨테이너화할 때 생성하는 방법은 다음과 같습니다. ① 아무것도 존재하지 않는 이미지(ex.Ubuntu, centOS)로 컨테이너를 생성. ② 애플리케이션을 위한 환경을 설치하고 소스 코드 등을 복사하여 잘 동작하는지 확인. ③ 컨테이너를 이미지화하여 커밋
이 방법을 사용하면 애플리케이션이 동작하는 환경을 구성하기 위해 일일이 수작업으로 패키지를 설치하고 소스 코드를 Git로 클론하거나 호스트에서 복사해야 합니다. 물론 직접 컨테이너로 애플리케이션을 구동해보고 이미지로 커밋하기 때문에 이미지 동작을 보장할 수 있다는 점도 있습니다. 이 방법을 사용하면 애플리케이션이 동작하는 환경을 구성하기 위해 일일이 수작업으로 패키지를 설치하고 소스 코드를 Git로 클론하거나 호스트에서 복사해야 합니다. 물론 직접 컨테이너로 애플리케이션을 구동해보고 이미지로 커밋하기 때문에 이미지 동작을 보장할 수 있다는 점도 있습니다.
Docker는 위와 같은 일련의 프로세스를 쉽게 기록하고 실행할 수 있는 docker build 명령을 제공합니다. 완성된 이미지를 생성하기 위해 컨테이너에 설치할 필요가 있는 패키지, 추가할 필요가 있는 소스 코드, 실행할 필요가 있는 명령어나 셸 스크립트 등을 하나의 파일에 기록해 두면 Docker는 이 파일을 불러와 컨테이너에서 작업을 수행한 후 이미지로 만듭니다. 이러한 작업을 기록한 파일의 이름을 Dockerfile이라고 하며 빌드 명령은 Dockerfile을 읽고 이미지를 생성합니다. Dockerfile을 사용하면 직접 컨테이너를 생성하고 이미지로 커밋하는 번거로움을 줄일 수 있을 뿐만 아니라 Git와 같은 개발 도구를 통해 애플리케이션 빌드와 배포를 자동화할 수 있습니다. Dockerfile은 어플리케이션을 개발하는 용도 외에도 다양한 용도로 사용할 수 있습니다. 생성한 이미지를 Docker 허브 등을 통해 배포할 때 이미지 자체를 배포하는 대신 이미지를 생성하는 방법을 기록한 Dockerfile을 배포할 수 있습니다. 특히, 배포되는 이미지를 신뢰할 수 없거나 직접 이미지를 생성하여 사용하고자 한다면 Docker 허브에 업로드되어 있는 Dockerfile로 빌드하는 것도 하나의 방법이 될 수 있습니다. 물론 ‘컨테이너에서 작업을 마치고 이미지로 커밋하면 좋지 않을까’라는 의문이 생길 수도 있지만, 애플리케이션을 컨테이너화하기 위한 장기적인 관점에서 볼 때 Dockerfile을 만드는 것은 이미지 생성 방법을 기록할 뿐만 아니라 이미지 빌드, 배포 측면에서도 매우 유리합니다. 왜냐하면 어플리케이션에 필요한 패키지 설치 등을 명확하게 할 수 있고 이미지 생성을 자동화할 수 있고 쉽게 배포할 수 있기 때문입니다. 2. Dockerfile 명령어 Dockerfile을 쓰는 방법이나 명령어에 대해 더 자세히 알고 싶다면 Docker 공식 레퍼런스를 참고하세요. FROM -> 생성하는 화상의 베이스가 되는 화상을 결정하는 커맨드입니다. 모든 Dockerfile은 반드시 FROM 지시어를 한 번 이상 입력해야 하며, 이 FROM 지시어를 시작으로 Dockerfile을 작성합니다. 이미지 이름 포맷은 docker run에서 사용하는 이미지 이름과 동일합니다. 만약 사용할 이미지가 Docker 엔진에 없을 경우 자동으로 Docker 허브에서 pull을 시도합니다. LABEL -> 화상의 메타데이터를 설정하는 커맨드입니다. 메타데이터는 「키=값」의 형태로 보존되어 복수의 메타데이터가 보존되는 일이 있습니다. 추가된 메타데이터는 docker inspect 명령으로 확인할 수 있습니다. 화상의 메타데이터는 기본적으로 optional이기 때문에, 사용하지 않아도 됩니다. WORKDIR -> 커맨드를 실행하는 디렉토리를 지정하는 커맨드입니다. 리눅스에서 cd 명령어와 동일합니다. (Setworking 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는 호스트 OS 경로, dest는 이미지 상에서의 경로입니다. 만약 COPY packeage*.json./와 COPY를 사용했을 때는 호스트 OS의 현재 디렉토리 상에 있는 pacakke에서 시작하여 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에는 두 가지 형식이 있습니다. ① RUN <명령어> <command> (쉘 형식으로 작성해야 하며 쉘에서 실행됩니다. Linux 기본값은 /bin/sh-c이며 Windows 기본값은 /S/C입니다.) ② 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 명령어처럼 배열 형태로 사용할 수 있는 Docker는 위와 같은 일련의 프로세스를 쉽게 기록하고 실행할 수 있는 docker build 명령어를 제공합니다. 완성된 이미지를 생성하기 위해 컨테이너에 설치할 필요가 있는 패키지, 추가할 필요가 있는 소스 코드, 실행할 필요가 있는 명령어나 셸 스크립트 등을 하나의 파일에 기록해 두면 Docker는 이 파일을 불러와 컨테이너에서 작업을 수행한 후 이미지로 만듭니다. 이러한 작업을 기록한 파일의 이름을 Dockerfile이라고 하며,
우분투 から ENTERPOINT [“top”, “-b”]CMD [-c”] 우분투 から ENTERPOINT [“top”, “-b”]CMD [-c”]
3. Dockerfile로 이미지를 빌드하기 전에 Dockerfile 명령어를 알아봤기 때문에 Dockerfile로 이미지를 만듭니다. 다음은 노드 JS 이미지를 생성하는 Dockerfile 입니다. 3. 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ノード: 16LABEL maintainer=”ですSeunghwan Seo <[email protected] >”LABEL description=”ですスンファンのNode.js server”# アプリディレクトリを作成しますWORKDIR /app# Install app dependencies# 두 패키지 모두를 확실히 하기 위해 와일드카드가 사용됩니다. json AND package-lock.json은 이용 가능한 경우 #를 복사합니다. (npm@5+) COPY package*.json./RUN npm install #실가동용 코드를 빌드하고 있는 경우 npmci –only=production # 번들 앱의 소스 COPY . .EXPOSE 8080CMD [ “node”, “server.js” ] 을 실행합니다 ## nodejs-server## build:# docker build –force-rm -t nodejs-server .# run:# docker run –rm -it –name nodejs-server nodejs-server#FROMノード: 16LABEL maintainer=”ですSeunghwan Seo <[email protected] >”LABEL description=”ですスンファンのNode.js server”# アプリディレクトリを作成しますWORKDIR /app# Install app dependencies# 두 패키지 모두를 확실히 하기 위해 와일드카드가 사용됩니다. json AND package-lock.json은 이용 가능한 경우 #를 복사합니다. (npm@5+) COPY package*.json./RUN npm install #실가동용 코드를 빌드하고 있는 경우 npmci –only=production # 번들 앱의 소스 COPY . .EXPOSE 8080CMD [ “node”, “server.js” ] 을 실행합니다
Dockerfile을 빌드하기 전에 위의 Dockerfile을 간단하게 해석하면 FROM-> 노드 JS16 버전의 이미지를 가져옵니다. WORKDIR -> 커맨드를 실행하는 장소를/app/디렉토리로 이동합니다. COPY-> 호스트 OS의 현재 디렉토리 상에 있는 pacakge에서 시작하여 .json에서 끝나는 모든 파일을 복사하여 이미지 상의 경로로 현재 디렉토리에 모두 복사하는 명령을 실행합니다. RUN->npm install을 지정해 주었기 때문에 이미지 상에서 WORKDIR 명령어로 지정해 준 현재 위치인 /app/ 디렉토리에서 COPY 명령어로 package*.json을 복사 붙여넣고 npm install에 package*.json을 불러와 패키지를 설치합니다. COPY->COPY는 형태는 COPY이고 src는 호스트OS 경로, dest는 이미지 상에서 경로이기 때문에 위의 Dockerfile에서 COPY. 명령어는 호스트OS 상의 모든 파일과 디렉토리를 이미지 상의/app/위치에 모두 복사하라고 해석하면 됩니다. 즉, COPY…를 한 이유는 소스코드 변경사항을 이 레이어 뒤에 실행하기 위해서입니다. EXPOSE -> 8080 포트를 사용하면 expose합니다. CMD->셸에서 ‘node server.js’ 명령을 실행합니다. 이제 Dockerfile로 이미지를 작성합니다. 이하의 명령을 입력해 주세요. Dockerfile을 빌드하기 전에 위의 Dockerfile을 간단하게 해석하면 FROM-> 노드 JS16 버전의 이미지를 가져옵니다. WORKDIR -> 커맨드를 실행하는 장소를/app/디렉토리로 이동합니다. COPY-> 호스트 OS의 현재 디렉토리 상에 있는 pacakge에서 시작하여 .json에서 끝나는 모든 파일을 복사하여 이미지 상의 경로로 현재 디렉토리에 모두 복사하는 명령을 실행합니다. RUN->npm install을 지정해 주었기 때문에 이미지 상에서 WORKDIR 명령어로 지정해 준 현재 위치인 /app/ 디렉토리에서 COPY 명령어로 package*.json을 복사 붙여넣고 npm install에 package*.json을 불러와 패키지를 설치합니다. COPY->COPY는 형태는 COPY이고 src는 호스트OS 경로, dest는 이미지 상에서 경로이기 때문에 위의 Dockerfile에서 COPY. 명령어는 호스트OS 상의 모든 파일과 디렉토리를 이미지 상의/app/위치에 모두 복사하라고 해석하면 됩니다. 즉, COPY…를 한 이유는 소스코드 변경사항을 이 레이어 뒤에 실행하기 위해서입니다. EXPOSE -> 8080 포트를 사용하면 expose합니다. CMD->셸에서 ‘node server.js’ 명령을 실행합니다. 이제 Dockerfile로 이미지를 작성합니다. 이하의 명령을 입력해 주세요.
$ 도커 빌드 –force-rm-t nodejs-server:1.0.0 です。 $도커 빌드 –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 옵션 -> 중간에 생성되는 임시 컨테이너를 삭제합니다. -t 옵션 -> 생성되는 화상의 이름을 설정합니다. 위 명령어를 실행하면 nodejs-server: 1.0.0이라는 이름의 이미지가 생성됩니다. -t 옵션을 사용하지 않으면 16진수 형태의 이름으로 이미지가 저장되므로 가급적이면 -t 옵션을 사용하는 것이 좋습니다. docker build 명령의 마지막에는 Dockerfile이 저장되어 있는 경로를 입력합니다. 일반적으로 로컬에 저장된 Dockerfile을 사용하지만 외부 URL에서 Dockerfile 내용을 불러와 빌드할 수도 있습니다. 이 예에서는 로컬에 Dockerfile을 저장했기 때문에 (/)(현재 디렉토리)를 입력했습니다. –force-rm 옵션 -> 중간에 생성되는 임시 컨테이너를 삭제합니다.
빌드를 시작하면 위와 같은 내용이 출력되고 nodejs-server:1.0.0이라는 이름의 이미지가 생성됩니다. 컨테이너가 실행될 때 CMD에서 “node server.js” 명령으로 노드 JS 서버를 실행하도록 설정했기 때문에 컨테이너를 실행하면 노드 JS 서버가 실행됩니다. 그럼 다음 명령을 입력하여 생성된 이미지로 컨테이너를 실행해 봅시다. 빌드를 시작하면 위와 같은 내용이 출력되고 nodejs-server:1.0.0이라는 이름의 이미지가 생성됩니다. 컨테이너가 실행될 때 CMD에서 “node server.js” 명령으로 노드 JS 서버를 실행하도록 설정했기 때문에 컨테이너를 실행하면 노드 JS 서버가 실행됩니다. 그럼 다음 명령을 입력하여 생성된 이미지로 컨테이너를 실행해 봅시다.
$ docker round – d – P –name my_nodejs_server nodejs-server: 1.$0.0 $docker rund – 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]:[포트]/[파일명])4. 빌드과정을 알아보는 docker build 명령어를 입력하였을 때 다양한 내용이 출력되었지만, 대부분의 내용은 Dockerfile의 RUN 명령어를 실행하여 컨테이너 내부에서 발생한 표준출력이지만 이미지를 생성하는 부분은 자세히 살펴봐야 합니다. (1)빌드 컨텍스트란? 이미지 빌드를 시작하면 Docker는 먼저 빌드 컨텍스트를 불러옵니다. 빌드 컨텍스트란 이미지를 생성하는데 필요한 각종 파일, 소스 코드, 메타데이터 등을 포함하는 디렉토리를 의미하며, Dockerfile이 위치한 디렉토리가 빌드 컨텍스트가 됩니다. -P 옵션 이미지에 설정된 EXPOSE 의 모든 포토를 호스트에 접속하도록 설정합니다. 위의 예에서는 Dockerfile에서 EXPOSE를 80번으로 설정하였으며, 이는 이미지에 ‘컨테이너의 80번 포트를 사용한다’는 것을 의미합니다. 즉, 이미지를 생성하기 위한 Dockerfile을 작성하는 개발자로서는 EXPOSE를 이용하여 이미지가 실제로 사용될 때 어떤 포트가 사용되어야 하는지 명시할 수 있으며, 이미지를 사용하는 입장에서는 컨테이너 애플리케이션이 컨테이너 내부에서 어떤 포트를 사용하는지 알 수 있게 됩니다. -P옵션은 EXPOSE에서 노출된 포트를 호스트에서 사용 가능한 포트에 차례로 연결하므로 이 컨테이너가 호스트의 어떤 포트와 연결되었는지 확인해야 합니다. docker ps 또는 docker port 명령으로 컨테이너와 연결된 호스트의 포트를 확인할 수 있으며, 호스트의 IP와 이 포트로 컨테이너의 웹서버에 연결할 수 있습니다. ([호스트 IP]:[포트]/[파일명])4. 빌드과정을 알아보는 docker build 명령어를 입력하였을 때 다양한 내용이 출력되었지만, 대부분의 내용은 Dockerfile의 RUN 명령어를 실행하여 컨테이너 내부에서 발생한 표준출력이지만 이미지를 생성하는 부분은 자세히 살펴봐야 합니다. (1)빌드 컨텍스트란? 이미지 빌드를 시작하면 Docker는 먼저 빌드 컨텍스트를 불러옵니다. 빌드 컨텍스트란 이미지를 생성하는데 필요한 각종 파일, 소스 코드, 메타데이터 등을 포함하는 디렉토리를 의미하며, Dockerfile이 위치한 디렉토리가 빌드 컨텍스트가 됩니다.
컨테이너 내부에 연결하면 빌드 컨텍스트를 확인할 수 있습니다. 빌드 컨텍스트는 Dockerfile로 빌드되는 이미지에 파일을 추가할 때 사용됩니다. Dockerfile로 이미지에 파일을 추가하는 방법은 ADD, COPY 등의 명령어가 있습니다. 이러한 명령어는 빌드 컨텍스트의 파일을 이미지에 추가합니다. 위 예에서는 WORKDIR 명령으로 빌드패스를 /app으로 지정하여 빌드컨텍스트에서 package*.json 파일을 불러와 노드 JS서버를 빌드할 수 있습니다. 컨텍스트에 대한 정보는 이미지를 빌드할 때 출력된 콘텐츠의 맨 위에 위치합니다. 컨테이너 내부에 연결하면 빌드 컨텍스트를 확인할 수 있습니다. 빌드 컨텍스트는 Dockerfile로 빌드되는 이미지에 파일을 추가할 때 사용됩니다. Dockerfile로 이미지에 파일을 추가하는 방법은 ADD, COPY 등의 명령어가 있습니다. 이러한 명령어는 빌드 컨텍스트의 파일을 이미지에 추가합니다. 위 예에서는 WORKDIR 명령으로 빌드패스를 /app으로 지정하여 빌드컨텍스트에서 package*.json 파일을 불러와 노드 JS서버를 빌드할 수 있습니다. 컨텍스트에 대한 정보는 이미지를 빌드할 때 출력된 콘텐츠의 맨 위에 위치합니다.
컨텍스트는 docker build 명령의 마지막에 지정된 위치에 있는 파일을 모두 포함합니다. 깃(Git)과 같은 외부 URL로 Dockerfile을 가져오려면 해당 저장소(Repository)에 있는 파일과 서브모듈을 포함합니다. 따라서 Dockerfile이 위치한 곳에는 이미지 빌드에 필요한 파일만 있는 것이 바람직하며 루트 디렉터리(/)와 같은 곳에서 이미지를 빌드하지 않도록 주의해야 합니다. 컨텍스트는 단순한 파일뿐만 아니라 하위 디렉터리도 모두 포함이 되기 때문에 빌드에 불필요한 파일이 포함된다면 빌드 속도가 느려질 뿐만 아니라 호스트의 메모리를 과도하게 점유할 수도 있습니다. (2)dockerignore 파일. dockerignore 파일은 빌드 컨텍스트에 불필요한 파일이 포함되어 있는 것을 방지하기 위해 옷깃으로 사용한다. gitignore와 유사한 기능을 사용할 수 있으며. gitgnore 파일과 문법이 같습니다. 즉, dockerignore라고 하는 파일을 작성하면 빌드시에 이 파일에 명시된 이름의 파일을 콘텍스트에서 제외합니다.. dockerignore 파일을 콘텍스트의 최상위 루트, 즉 build 명령으로 오직 끝에 온 경로인 Dockerfile이 위치한 경로와 같은 곳에 위치해야 합니다. 아래는 dockerignore 파일 예시입니다. 컨텍스트는 docker build 명령의 마지막에 지정된 위치에 있는 파일을 모두 포함합니다. 깃(Git)과 같은 외부 URL로 Dockerfile을 가져오려면 해당 저장소(Repository)에 있는 파일과 서브모듈을 포함합니다. 따라서 Dockerfile이 위치한 곳에는 이미지 빌드에 필요한 파일만 있는 것이 바람직하며 루트 디렉터리(/)와 같은 곳에서 이미지를 빌드하지 않도록 주의해야 합니다. 컨텍스트는 단순한 파일뿐만 아니라 하위 디렉터리도 모두 포함이 되기 때문에 빌드에 불필요한 파일이 포함된다면 빌드 속도가 느려질 뿐만 아니라 호스트의 메모리를 과도하게 점유할 수도 있습니다. (2)dockerignore 파일. dockerignore 파일은 빌드 컨텍스트에 불필요한 파일이 포함되어 있는 것을 방지하기 위해 옷깃으로 사용한다. gitignore와 유사한 기능을 사용할 수 있으며. gitgnore 파일과 문법이 같습니다. 즉, dockerignore라고 하는 파일을 작성하면 빌드시에 이 파일에 명시된 이름의 파일을 콘텍스트에서 제외합니다.. dockerignore 파일을 콘텍스트의 최상위 루트, 즉 build 명령으로 오직 끝에 온 경로인 Dockerfile이 위치한 경로와 같은 곳에 위치해야 합니다. 아래는 dockerignore 파일 예시입니다.
test.html/html.html. テスト。H[수학] 시험문제.html/html./html. テスト。HTM?
컨텍스트에서 제외하는 파일의 경로는 Dockerfile이 존재하는 경로를 기반으로 합니다. 예를 들어 build 명령에서 설정한 경로가 현재 디렉토리에서 /home/seosh817이라면 *.html은 /home/seosh817/*.html에 해당하는 모든 파일을 의미합니다. 마찬가지로 */*.html은 /home/seosh817/*/*.html에 해당하는 파일을 제외한다는 의미입니다. 즉, */로 구분되는 디렉토리는 어떤 디렉토리 레벨을 의미하며 중간에 어떤 디렉토리가 와도 상관없습니다. test.html?는 test.htm을 접두어로 하고 “?” 위치에 임의의 한 자리 글자가 들어가는 파일을 제외합니다. 즉, dockerignore에 test.html?을 지정하면 test.htma, test.htmb… 등이 컨텍스트에서 제외됩니다. 제외 목록에는 해당되지만 특수한 파일만 포함하도록 설정하려면 ‘!’를 사용합니다. ‘!’는 특정 파일을 제외하지 않는 것을 의미합니다. 아래 예는 확장자가 .html인 파일을 모두 제외하지만 test로 시작하는 html 파일을 컨텍스트에서 제외하지 않습니다. 컨텍스트에서 제외하는 파일의 경로는 Dockerfile이 존재하는 경로를 기반으로 합니다. 예를 들어 build 명령에서 설정한 경로가 현재 디렉토리에서 /home/seosh817이라면 *.html은 /home/seosh817/*.html에 해당하는 모든 파일을 의미합니다. 마찬가지로 */*.html은 /home/seosh817/*/*.html에 해당하는 파일을 제외한다는 의미입니다. 즉, */로 구분되는 디렉토리는 어떤 디렉토리 레벨을 의미하며 중간에 어떤 디렉토리가 와도 상관없습니다. test.html?는 test.htm을 접두어로 하고 “?” 위치에 임의의 한 자리 글자가 들어가는 파일을 제외합니다. 즉, dockerignore에 test.html?을 지정하면 test.htma, test.htmb… 등이 컨텍스트에서 제외됩니다. 제외 목록에는 해당되지만 특수한 파일만 포함하도록 설정하려면 ‘!’를 사용합니다. ‘!’는 특정 파일을 제외하지 않는 것을 의미합니다. 아래 예는 확장자가 .html인 파일을 모두 제외하지만 test로 시작하는 html 파일을 컨텍스트에서 제외하지 않습니다.
*.html ! 테스트*.html *.html ! 테스트*.html
(3) Dockerfile을 이용한 컨테이너 생성과 커밋빌 명령어는 Dockerfile에 기록된 대로 컨테이너를 실행한 후 완성된 이미지를 만들어냅니다. 하지만이미지를만드는프로세스가 하나의 컨테이너에서 발생하는 것은 아닙니다. 이미지를 빌드할 때 나오는 아래와 같은 “Removing intermediate container [container id]”의 출력 결과로부터 어느 정도 추측할 수 있습니다. (3) Dockerfile을 이용한 컨테이너 생성과 커밋빌 명령어는 Dockerfile에 기록된 대로 컨테이너를 실행한 후 완성된 이미지를 만들어냅니다. 하지만이미지를만드는프로세스가 하나의 컨테이너에서 발생하는 것은 아닙니다. 이미지를 빌드할 때 나오는 아래와 같은 “Removing intermediate container [container id]”의 출력 결과로부터 어느 정도 추측할 수 있습니다.
각 단계는 Dockerfile에 기록된 명령어에 해당합니다. FROM, RUN, WORKDIR 등의 명령어가 실행될 때마다 새로운 컨테이너가 하나씩 생성되고 이를 이미지로 커밋합니다. 즉, Dockerfile에서 명령어의 한 줄이 실행될 때마다 이전 Step에서 생성된 이미지에 따라 새로운 컨테이너가 생성되고 Dockerfile에 적힌 명령어를 실행하여 다시 새로운 이미지 레이어로 저장됩니다. 각 단계는 Dockerfile에 기록된 명령어에 해당합니다. FROM, RUN, WORKDIR 등의 명령어가 실행될 때마다 새로운 컨테이너가 하나씩 생성되고 이를 이미지로 커밋합니다. 즉, Dockerfile에서 명령어의 한 줄이 실행될 때마다 이전 Step에서 생성된 이미지에 따라 새로운 컨테이너가 생성되고 Dockerfile에 적힌 명령어를 실행하여 다시 새로운 이미지 레이어로 저장됩니다.
따라서 이미지 빌드가 완료되면 Dockerfile의 명령어 수만큼의 레이어가 존재하게 되고 중간에 컨테이너도 동일한 수만큼 생성되고 삭제됩니다. 위 출력 결과에서 Removing intermediate container…는 중간에 이미지 레이어를 생성하기 위해 일시적으로 생성된 컨테이너를 삭제하는 것으로 삭제되기 전에 출력되는 ID는 커밋된 이미지 레이어를 의미합니다. (4)캐시를 이용한 이미지 빌드 한번 이미지 빌드를 마친 후 다시 같은 빌드를 수행하면 이전 이미지 빌드에서 사용한 캐시를 사용합니다. 아래 내용을 파일로 저장하고 다시 이미지를 빌드해 보겠습니다. 아래의 Dockerfile은 위에서 빌드한 이미지에서 몇 가지 명령어를 삭제했습니다. 따라서 이미지 빌드가 완료되면 Dockerfile의 명령어 수만큼의 레이어가 존재하게 되고 중간에 컨테이너도 동일한 수만큼 생성되고 삭제됩니다. 위 출력 결과에서 Removing intermediate container…는 중간에 이미지 레이어를 생성하기 위해 일시적으로 생성된 컨테이너를 삭제하는 것으로 삭제되기 전에 출력되는 ID는 커밋된 이미지 레이어를 의미합니다. (4)캐시를 이용한 이미지 빌드 한번 이미지 빌드를 마친 후 다시 같은 빌드를 수행하면 이전 이미지 빌드에서 사용한 캐시를 사용합니다. 아래 내용을 파일로 저장하고 다시 이미지를 빌드해 보겠습니다. 아래의 Dockerfile은 위에서 빌드한 이미지에서 몇 가지 명령어를 삭제했습니다.
FROM 노드: 16LABEL maintainer=”입니다 Seunghwan Seo <[email protected] >”LABEL description=”입니다 승환의 Node.js 서버입니다 WORKDIR /appCOPY 패키지*.json./npm 업데이트를 실행합니다 npm installCOPY를 실행합니다. FROM 노드: 16LABEL maintainer=”입니다 Seunghwan Seo <[email protected] >”LABEL description=”입니다 승환의 Node.js 서버입니다 WORKDIR /appCOPY 패키지*.json./npm 업데이트를 실행합니다 npm installCOPY를 실행합니다.
Dockerfile의 이름을 Dockerfile2로 저장했습니다. docker build 명령의 -f(-file) 옵션에서 Dockerfile의 이름을 지정할 수 있습니다. 그래서 docker build 명령어를 docker build-f Dockerfile2-t cache: 0.0.0.0./로 입력하여 Dockerfile2를 빌드합니다. Dockerfile의 이름을 Dockerfile2로 저장했습니다. docker build 명령의 -f(-file) 옵션에서 Dockerfile의 이름을 지정할 수 있습니다. 그래서 docker build 명령어를 docker build-f Dockerfile2-t cache: 0.0.0.0./로 입력하여 Dockerfile2를 빌드합니다.
$ docker build -f Dockerfile2 – tcache: 0.0. / $docker build -f Dockerfile2 – tcache: 0.0./
Using cache라는 출력 내용과 함께 별도의 빌드 과정이 이루어지지 않고 바로 이미지가 생성되었습니다. 이전에 빌드한 Dockerfile에 동일한 내용이 있는 경우 build 명령어는 이를 새로 빌드하지 않고 동일한 명령줄까지 이전에 사용한 이미지 레이어를 활용하여 이미지를 생성합니다. 이는 동일한 명령어를 여러 번 실행해야 하는 여러 이미지를 빌드하거나 빌드 중에 Dockerfile 문법이나 기타 오류가 발생할 때 불필요하게 다시 명령어를 실행하지 않도록 합니다. * 만약 이미지 빌드 중에 오류가 발생한다면요? 이미지 빌드 중 오류가 발생할 경우 build 명령이 중지되며 이미지 레이어 생성을 위해 마지막으로 생성된 임시 컨테이너가 삭제되지 않은 채 남아 있습니다. 또한 이미지 빌드가 완전하지 않기 때문에 -t 옵션 값으로 지정된 이미지의 이름이 아닌 ‘none’: ‘none’으로 이미지가 생성됩니다. 이러한 이미지를 삭제하려면 dockermi [imageid] 명령어로 이미지를 삭제하면 됩니다. Using cache라는 출력 내용과 함께 별도의 빌드 과정이 이루어지지 않고 바로 이미지가 생성되었습니다. 이전에 빌드한 Dockerfile에 동일한 내용이 있는 경우 build 명령어는 이를 새로 빌드하지 않고 동일한 명령줄까지 이전에 사용한 이미지 레이어를 활용하여 이미지를 생성합니다. 이는 동일한 명령어를 여러 번 실행해야 하는 여러 이미지를 빌드하거나 빌드 중에 Dockerfile 문법이나 기타 오류가 발생할 때 불필요하게 다시 명령어를 실행하지 않도록 합니다. * 만약 이미지 빌드 중에 오류가 발생한다면요? 이미지 빌드 중 오류가 발생할 경우 build 명령이 중지되며 이미지 레이어 생성을 위해 마지막으로 생성된 임시 컨테이너가 삭제되지 않은 채 남아 있습니다. 또한 이미지 빌드가 완전하지 않기 때문에 -t 옵션 값으로 지정된 이미지의 이름이 아닌 ‘none’: ‘none’으로 이미지가 생성됩니다. 이러한 이미지를 삭제하려면 dockermi [imageid] 명령어로 이미지를 삭제하면 됩니다.
그러나 때로는 오히려 캐시 기능이 필요하지 않을 수도 있습니다. 위 그림과 같이 GitHub와 같은 소스코드 저장소에서 gitclone과 같은 명령어를 사용하여 빌드할 때가 이에 해당합니다. Dockerfile에 RUN git clone…을 사용하여 이미지를 빌드한 경우 RUN에 대한 이미지 레이어를 캐시로 계속 사용하기 때문에 실제 Git 저장소에서 리비전 관리가 이루어지더라도 매번 빌드를 할 때마다 고정된 소스 코드가 clone됩니다. 이 경우 캐시를 사용하지 않으면 buile 명령에 no-cahe 옵션을 추가합니다. –no-cahe 옵션을 사용하면 기존 빌드에 사용된 캐시를 사용하지 않고 Dockerfile을 처음부터 이미지 레이어로 다시 빌드합니다. 그러나 때로는 오히려 캐시 기능이 필요하지 않을 수도 있습니다. 위 그림과 같이 GitHub와 같은 소스코드 저장소에서 gitclone과 같은 명령어를 사용하여 빌드할 때가 이에 해당합니다. Dockerfile에 RUN git clone…을 사용하여 이미지를 빌드한 경우 RUN에 대한 이미지 레이어를 캐시로 계속 사용하기 때문에 실제 Git 저장소에서 리비전 관리가 이루어지더라도 매번 빌드를 할 때마다 고정된 소스 코드가 clone됩니다. 이 경우 캐시를 사용하지 않으면 buile 명령에 no-cahe 옵션을 추가합니다. –no-cahe 옵션을 사용하면 기존 빌드에 사용된 캐시를 사용하지 않고 Dockerfile을 처음부터 이미지 레이어로 다시 빌드합니다.
$ docker build –no-cache -f Dockerfile2 – tcache: 0.0/ $docker 빌드 –no-cache -f Dockerfile2 – tcache: 0.0/
또는 캐시로 사용할 이미지를 직접 지정할 수도 있습니다. –cache-from 옵션 -> 특정 Dockerfile을 확장하여 사용하면 기존 Dockerfile로 빌드한 이미지를 빌드 캐시로 사용할 수 있습니다. 예를 들어 Docker 허브의 nginx 공식 저장소에서 nginx:latest 이미지를 빌드하는 Dockerfile에 일부 내용을 추가하여 사용하면 로컬의 nginx:latest 이미지를 캐시로 사용할 수 있습니다. 또는 캐시로 사용할 이미지를 직접 지정할 수도 있습니다. –cache-from 옵션 -> 특정 Dockerfile을 확장하여 사용하면 기존 Dockerfile로 빌드한 이미지를 빌드 캐시로 사용할 수 있습니다. 예를 들어 Docker 허브의 nginx 공식 저장소에서 nginx:latest 이미지를 빌드하는 Dockerfile에 일부 내용을 추가하여 사용하면 로컬의 nginx:latest 이미지를 캐시로 사용할 수 있습니다.
$ 도커 빌드 –cache-from nginx my-extend_nginx:0.0 です。 $도커 빌드 –cache-from nginx my-extend_nginx:0.0 です。