Dockerfile Best Practice
이 문서는 Dockerfile 관련하여 Best Practice에 대한 내용을 공부도 할겸 번역하였다.
Last updated
Was this helpful?
이 문서는 Dockerfile 관련하여 Best Practice에 대한 내용을 공부도 할겸 번역하였다.
Last updated
Was this helpful?
원본 :
이 문서에서는 효율적인 이미지를 구축하기위한 권장 모범 사례와 방법을 다룹니다.
Docker는 주어진 이미지를 빌드하는 데 필요한 모든 명령이 순서대로 포함 된 텍스트 파일 인 Dockerfile
에서 지침을 읽어 이미지를 자동으로 빌드합니다. Dockerfile
은 에서 찾을 수 있는 특정 형식 및 지침 집합을 준수합니다.
Docker 이미지는 각각 Dockerfile 명령어를 나타내는 읽기 전용 레이어로 구성됩니다. 레이어는 차례로 쌓여 있고 각 레이어는 이전 레이어의 변경 사항에 대한 부분입니다.
아래 Dockerfile
을 참고하십시오.
각 명령어는 하나의 레이어를 만듭니다.
FROM
은 ubuntu : 18.04
Docker 이미지에서 레이어를 생성합니다.
COPY
는 Docker 클라이언트의 현재 디렉토리에서 파일을 추가합니다.
RUN
은 make
로 애플리케이션을 빌드합니다.
CMD
는 컨테이너 내에서 실행할 명령을 지정합니다.
이미지를 실행하고 컨테이너를 생성 할 때 기본 레이어 위에 새 쓰기 가능한 계층("컨테이너 레이어")를 추가합니다. 새 파일 쓰기, 기존 파일 수정 및 파일 삭제와 같이 실행중인 컨테이너에 대한 모든 변경 사항은 이 쓰기 가능한 컨테이너 계층에 기록됩니다.
이미지 레이어(및 Docker가 이미지를 빌드하고 저장하는 방법)에 대한 자세한 내용은 를 참조하세요.
Dockerfile
에서 정의한 이미지는 가능한 한 임시적인 컨테이너를 생성해야합니다. "일시적"이란 컨테이너를 중지하고 폐기 한 다음 다시 빌드하고 절대 최소 설정 및 구성으로 교체 할 수 있음을 의미합니다.
docker build
명령을 실행하면 현재 작업 디렉토리를 빌드 컨텍스트 라고 합니다. 기본적으로 Dockerfile은 이곳에 있는 것으로 간주되지만 파일 플래그 (-f
)를 사용하여 다른 위치를 지정할 수도 있습니다. Dockerfile
이 실제로 어디에 있든 관계없이 현재 디렉터리에 있는 파일 및 디렉터리의 모든 하위 콘텐츠는 빌드 컨텍스트로 Docker 데몬에 전송됩니다.
빌드 컨텍스트 예제
빌드 컨텍스트에 대한 디렉토리를 만들고 그 안에
cd
로 들어갑니다. 'hello'라는 텍스트 파일에 "hello"를 쓰고 'cat'을 실행하는 Dockerfile을 만듭니다. 빌드 컨텍스트 (.
) 내에서 이미지를 빌드합니다.
Dockerfile
과hello
를 별도의 디렉토리로 이동하고 이미지의 두 번째 버전을 빌드합니다 (마지막 빌드의 캐시에 의존하지 않음).-f
를 사용하여 Dockerfile을 가리키고 빌드 컨텍스트의 디렉터리를 지정합니다.
이미지를 빌드하는 데 필요하지 않은 파일을 실수로 포함하면 빌드 컨텍스트와 이미지 크기가 커집니다. 이렇게하면 이미지를 빌드하는 시간, 이미지를 가져오고 푸시하는 시간, 컨테이너 런타임 크기가 늘어날 수 있습니다. 빌드 컨텍스트의 크기를 확인하려면 Dockerfile
을 빌드 할 때 다음과 같은 메시지를 찾으십시오.
stdin
을 통해 Dockerfile 파이프Docker는 로컬 또는 원격 빌드 컨텍스트를 사용하여stdin
을 통해Dockerfile
을 파이핑하여 이미지를 빌드 할 수 있습니다. stdin
을 통해 Dockerfile
을 파이핑하는 것은 Dockerfile을 디스크에 쓰지 않고 일회성 빌드를 수행하는 데 유용 할 수 있습니다. 또는 Dockerfile
이 생성되더라도 이후에 지속되지 않아야합니다.
예를 들어 다음 명령은 동일합니다.
예제를 선호하는 접근 방식 또는 사용 사례에 가장 적합한 접근 방식으로 대체 할 수 있습니다.
빌드 컨텍스트를 보내지 않고 STDIN에서 DOCKERFILE을 사용하여 이미지 빌드
빌드 컨텍스트로 추가 파일을 보내지 않고 stdin
의 Dockerfile
을 사용하여 이미지를 빌드하려면 이 구문을 사용하십시오. 하이픈(-
)은 PATH
의 위치를 취하고 Docker가 디렉토리 대신 stdin
에서 빌드 컨텍스트 (Dockerfile
만 포함)를 읽도록 지시합니다.
다음 예제는 stdin
을 통해 전달되는 Dockerfile
을 사용하여 이미지를 빌드합니다. 데몬에 빌드 컨텍스트로 파일이 전송되지 않습니다.
빌드 컨텍스트를 생략하면 Dockerfile
이 파일을 이미지에 복사 할 필요가없는 상황에서 유용 할 수 있으며 데몬에 파일이 전송되지 않으므로 빌드 속도가 향상됩니다.
Note: 이 구문을 사용하면
COPY
또는ADD
를 사용하는 Dockerfile 빌드 시도가 실패합니다. 다음 예는 이를 설명합니다.
stdin의 Dockerfile을 사용하여 로컬 빌드 컨텍스트에서 빌드
이 구문을 사용하여 로컬 파일 시스템의 파일을 사용하지만 stdin
의 Dockerfile
을 사용하여 이미지를 빌드합니다. 구문은 -f
(또는 --file
) 옵션을 사용하여 사용할 Dockerfile
을 지정하고, 하이픈(-
)을 파일 이름으로 사용하여 Docker가 stdin
에서 Dockerfile
을 읽도록 지시합니다.
stdin의 Dockerfile을 사용하여 원격 빌드 컨텍스트에서 빌드
이 구문을 사용하여 stdin
의 Dockerfile
을 사용하여 원격 git
저장소의 파일을 사용하여 이미지를 빌드합니다. 구문은 -f
(또는 --file
) 옵션을 사용하여 사용할 Dockerfile
을 지정하고, 하이픈(-
)을 파일 이름으로 사용하여 Docker가 stdin
에서 Dockerfile
을 읽도록 지시합니다.
이 구문은 Dockerfile
이 포함되지 않은 저장소에서 이미지를 빌드하려는 경우 또는 저장소의 자체 포크를 유지하지 않고 사용자 정의 Dockerfile
로 빌드하려는 경우에 유용 할 수 있습니다.
상세 내용
원격 Git 리포지토리를 빌드 컨텍스트로 사용하여 이미지를 빌드 할 때 Docker는 로컬 머신에서 리포지토리의
git clone
을 수행하고 해당 파일을 빌드 컨텍스트로 데몬에 보냅니다. 이 기능을 사용하려면docker build
명령을 실행하는 호스트에git
이 설치되어 있어야합니다.
예를 들어 빌드에 여러 레이어가 포함 된 경우 변경 빈도가 낮은 것 (빌드 캐시 재사용 가능)에서 더 자주 변경되는 순서로 순서를 지정할 수 있습니다.
애플리케이션 구축에 필요한 도구 설치
라이브러리 종속성 설치 또는 업데이트
응용 프로그램 생성
Go 애플리케이션 용 Dockerfile은 다음과 같습니다.
복잡성, 종속성, 파일 크기 및 빌드 시간을 줄이려면 "있으면 좋을 것" 이라는 이유로 추가 또는 불필요한 패키지를 설치하지 마십시오. 예를 들어 데이터베이스 이미지에 텍스트 편집기를 포함 할 필요가 없습니다.
각 컨테이너에는 하나의 관심사가 있어야합니다. 애플리케이션을 여러 컨테이너로 분리하면 더 쉽게 수평으로 확장하고 컨테이너를 재사용 할 수 있습니다. 예를 들어, 웹 애플리케이션 스택은 분리 된 방식으로 웹 애플리케이션, 데이터베이스 및 인 메모리 캐시를 관리하기 위해 각각 고유한 이미지가있는 3개의 개별 컨테이너로 구성 될 수 있습니다.
이전 버전의 Docker에서는 성능을 보장하기 위해 이미지의 레이어 수를 최소화하는 것이 중요했습니다. 이 제한을 줄이기 위해 다음 기능이 추가되었습니다.
RUN
,COPY
,ADD
명령어 만 레이어를 생성합니다.
다른 지침은 임시 중간 이미지를 만들고 빌드 크기를 늘리지 않습니다.
가능하면 [다단계 빌드] (multistage-build.md)를 사용하고 필요한 아티팩트 만 최종 이미지에 복사합니다. 이를 통해 최종 이미지의 크기를 늘리지 않고도 중간 빌드 단계에 도구 및 디버그 정보를 포함 할 수 있습니다.
가능하면 여러 줄 인수를 영숫자 순으로 정렬하여 나중에 쉽게 변경할 수 있습니다. 이렇게하면 패키지 중복을 방지하고 목록을 훨씬 쉽게 업데이트 할 수 있습니다. 또한 PR을 읽고 검토하기가 훨씬 쉬워집니다. 백 슬래시 (\
) 앞에 공백을 추가하는 것도 도움이됩니다.
이미지를 빌드 할 때 Docker는 Dockerfile
의 지침을 단계별로 수행하여 지정된 순서대로 각각을 실행합니다. 각 명령어를 검사 할 때 Docker는 새(중복) 이미지를 생성하는 대신 캐시에서 재사용 할 수 있는 기존 이미지를 찾습니다.
캐시를 전혀 사용하지 않으려면 docker build
명령에 --no-cache = true
옵션을 사용할 수 있습니다. 그러나 Docker가 캐시를 사용하도록 허용하는 경우 일치하는 이미지를 찾을 수 있는 경우와 찾을 수 없는 경우를 이해하는 것이 중요합니다. Docker가 따르는 기본 규칙은 다음과 같습니다.
이미 캐시에 있는 상위 이미지로 시작하여 다음 명령어를 해당 기본 이미지에서 파생 된 모든 하위 이미지와 비교하여 그 중 하나가 정확히 동일한 명령어를 사용하여 빌드되었는지 확인합니다. 그렇지 않으면 캐시가 무효화됩니다.
대부분의 경우 Dockerfile
의 명령어를 하위 이미지 중 하나와 비교하는 것만으로도 충분합니다.
그러나 특정 지침에는 더 많은 검사와 설명이 필요합니다.
ADD
및 COPY
명령의 경우 이미지에있는 파일의 내용을 검사하고 각 파일에 대해 체크섬을 계산합니다.
파일의 마지막 수정 및 마지막 액세스 시간은이 체크섬에서 고려되지 않습니다.
캐시 조회 중에 체크섬은 기존 이미지의 체크섬과 비교됩니다.
내용 및 메타 데이터와 같이 파일에서 변경된 사항이 있으면 캐시가 무효화됩니다.
ADD
및 COPY
명령을 제외하고 캐시 검사는 캐시 일치를 확인하기 위해 컨테이너의 파일을 확인하지 않습니다.
예를 들어 RUN apt-get -y update
명령을 처리 할 때 컨테이너에서 업데이트 된 파일은 캐시 적중이 존재하는지 확인하기 위해 검사되지 않습니다.
이 경우 명령 문자열 자체 만 일치를 찾는 데 사용됩니다.
캐시가 무효화되면 모든 후속 Dockerfile
명령이 새 이미지를 생성하고 캐시는 사용되지 않습니다.
이러한 권장 사항은 효율적이고 유지 관리 가능한 Dockerfile
을 만드는 데 도움이되도록 설계되었습니다.
이미지에 레이블을 추가하여 프로젝트별로 이미지를 구성하고, 라이센싱 정보를 기록하고, 자동화를 지원하거나 기타 다른 이유로 사용할 수 있습니다.
각 라벨에 LABEL
로 시작하고 하나 이상의 키-값 쌍으로 시작하는 줄을 추가합니다.
다음 예는 다양한 허용 형식을 보여줍니다. 설명 주석이 인라인으로 포함됩니다.
공백이있는 문자열은 따옴표로 묶거나 or 공백을 이스케이프 해야합니다. 내부 따옴표 (
"
)도 이스케이프해야합니다.
이미지에는 둘 이상의 레이블이있을 수 있습니다. Docker 1.10 이전에는 추가 레이어가 생성되지 않도록 모든 라벨을 단일 LABEL
명령어로 결합하는 것이 좋습니다. 더 이상 필요하지 않지만 레이블 결합은 계속 지원됩니다.
위의 내용은 다음과 같이 작성할 수도 있습니다.
길거나 복잡한 RUN
문을 백 슬래시로 구분된 여러 줄로 분할하여 Dockerfile
을 더 읽기 쉽고 이해하기 쉽고 유지 관리하기 쉽게 만듭니다.
apt-get
아마도 RUN
의 가장 일반적인 사용 사례는 apt-get
의 애플리케이션 일 것입니다. 패키지를 설치하기 때문에 RUN apt-get
명령에는 주의해야 할 몇가지 문제가 있습니다.
항상 동일한 RUN
문에서 RUN apt-get update
와 apt-get install
을 결합하십시오. 예를 들면 :
RUN
문에서 apt-get update
만 사용하면 캐싱 문제가 발생하고 후속 apt-get install
명령이 실패합니다.
예를 들어 Dockerfile이 있다고 가정합니다.
이미지를 빌드 한 후 모든 레이어는 Docker 캐시에 있습니다.
나중에 추가 패키지를 추가하여 apt-get install
을 수정한다고 가정합니다.
Docker는 초기 및 수정 된 지침을 동일하게보고 이전 단계의 캐시를 재사용합니다.
결과적으로 빌드가 캐시 된 버전을 사용하기 때문에 apt-get update
가 실행되지 않습니다.
apt-get update
가 실행되지 않기 때문에 빌드가 잠재적으로 curl
및 nginx
패키지의 오래된 버전을 가져올 수 있습니다.
RUN apt-get update && apt-get install -y
를 사용하면 Dockerfile이 추가 코딩이나 수동 개입없이 최신 패키지 버전을 설치할 수 있습니다. 이 기술을 "캐시 무효화" 라고합니다.
패키지 버전을 지정하여 캐시 무효화를 수행 할 수도 있습니다.
이를 버전 고정이라고합니다. 예를 들면 다음과 같습니다.
버전 고정은 캐시에있는 항목에 관계없이 빌드가 특정 버전을 검색하도록 합니다. 이 기술은 또한 필수 패키지의 예상치 못한 변경으로 인한 실패를 줄일 수 있습니다.
다음은 모든 apt-get
권장 사항을 보여주는 잘 구성된 RUN
명령어입니다.
s3cmd
인수는 1.1. *
버전을 지정합니다. 이미지가 이전에 오래된 버전을 사용한 경우 새 버전을 지정하면 apt-get update
캐시 버스트가 발생하고 새 버전이 설치됩니다.
각 줄에 패키지를 나열하면 패키지 복제 실수를 방지 할 수 있습니다.
또한 /var/lib/apt/lists
를 제거하여 apt 캐시를 정리하면 apt 캐시가 레이어에 저장되지 않으므로 이미지 크기가 줄어 듭니다.
RUN
구문은 apt-get update
로 시작하므로 패키지 캐시는 항상 apt-get install
전에 새로 고쳐집니다.
파이프 사용
일부 RUN
명령은 다음 예와 같이 파이프 문자 (|
)를 사용하여 한 명령의 출력을 다른 명령으로 파이프하는 기능에 따라 다릅니다.
Docker는 파이프에서 마지막 작업의 종료 코드만 평가하여 성공 여부를 확인하는 /bin/sh -c
인터프리터를 사용하여 이러한 명령을 실행합니다. 위의 예제에서 이 빌드 단계는 wget
명령이 실패하더라도 wc -l
명령이 성공하는 한 성공하고 새 이미지를 생성합니다.
파이프의 어느 단계에서든 오류로 인해 명령이 실패하도록하려면 set -o pipefail &&
를 앞에 추가하여 예기치 않은 오류로 인해 빌드가 실수로 성공하지 못하도록 합니다. 예를 들면 :
모든 쉘이
-o pipefail
옵션을 지원하는 것은 아닙니다.Debian 기반 이미지의
dash
쉘과 같은 경우RUN
의 실행 형식을 사용하여pipefail
옵션을 지원하는 쉘을 명시 적으로 선택하는 것이 좋습니다. 예를 들면 :
CMD
명령은 인수와 함께 이미지에 포함 된 소프트웨어를 실행하는 데 사용해야합니다.
CMD
는 거의 항상 CMD ["executable", "param1", "param2"…]
형식으로 사용되어야합니다.
따라서 이미지가 Apache 및 Rails와 같은 서비스 용인 경우 CMD ["apache2", "-DFOREGROUND"]
와 같은 것을 실행합니다.
실제로 이러한 형식의 지침은 모든 서비스 기반 이미지에 권장됩니다.
EXPOSE
명령어는 컨테이너가 연결을 수신하는 포트를 나타냅니다. 따라서 응용 프로그램에 대해 일반적인 일반 포트를 사용해야합니다.
예를 들어 Apache 웹 서버가 포함 된 이미지는 EXPOSE 80
을 사용하고 MongoDB를 포함하는 이미지는 EXPOSE 27017
등을 사용합니다.
외부 액세스를 위해 사용자는 지정된 포트를 자신이 선택한 포트에 매핑하는 방법을 나타내는 플래그와 함께 docker run
을 실행할 수 있습니다.
컨테이너 연결을 위해 Docker는 수신자 컨테이너에서 소스까지의 경로에 대한 환경 변수를 제공합니다 (예 :MYSQL_PORT_3306_TCP
).
새 소프트웨어를 더 쉽게 실행하려면 ENV
를 사용하여 컨테이너가 설치하는 소프트웨어의 PATH
환경 변수를 업데이트 할 수 있습니다.
예를 들어 ENV PATH /usr/local/nginx/bin:$PATH
는 CMD ["nginx"]
가 작동하도록 합니다.
ENV
명령어는 Postgres의 PGDATA
와 같이 컨테이너화하려는 서비스에 특정한 필수 환경 변수를 제공하는데도 유용합니다.
마지막으로, ENV
는 일반적으로 사용되는 버전 번호를 설정하는데도 사용할 수 있으므로 다음 예제와 같이 버전 범프를 유지하기가 더 쉽습니다.
Similar to having constant variables in a program (as opposed to hard-coding values), this approach lets you change a single ENV
instruction to auto-magically bump the version of the software in your container.
각 ENV
라인은 RUN
명령과 마찬가지로 새로운 중간 레이어를 생성합니다.
즉, 향후 계층에서 환경 변수를 설정해제 하더라도 이 계층에서 계속 유지되며 해당 값을 덤프 할 수 없습니다.
다음과 같이 Dockerfile을 만든 다음 빌드하여이를 테스트 할 수 있습니다.
이를 방지하고 실제로 환경 변수를 설정해제 하려면 쉘 명령과 함께 RUN
명령을 사용하여 단일 레이어에서 변수를 설정, 사용 및 설정해제하십시오.
;
또는 &&
로 명령을 분리 할 수 있습니다. 두 번째 방법을 사용하고 명령 중 하나가 실패하면 docker build
도 실패합니다. 이것은 일반적으로 좋은 생각입니다.
Linux Dockerfiles의 줄 연속 문자로 \
를 사용하면 가독성이 향상됩니다.
모든 명령을 쉘 스크립트에 넣고 RUN
명령이 해당 쉘 스크립트를 실행하도록 할 수도 있습니다.
ADD
와 COPY
는 기능적으로 유사하지만 일반적으로 COPY
가 선호됩니다. ADD
보다 투명하기 때문입니다.
COPY
는 컨테이너에 로컬 파일의 기본 복사 만 지원하는 반면 ADD
에는 즉시 명확하지 않은 일부 기능 (로컬 전용 tar 추출 및 원격 URL 지원)이 있습니다.
따라서 ADD
의 가장 좋은 용도는 ADD rootfs.tar.xz /
에서와 같이 로컬 tar 파일을 이미지로 자동 추출하는 것입니다.
컨텍스트와 다른 파일을 사용하는 여러 Dockerfile
단계가 있는 경우 한 번에 모두가 아닌 개별적으로 COPY
하십시오.
이렇게하면 특별히 필요한 파일이 변경된 경우에만 각 단계의 빌드 캐시가 무효화됩니다 (단계를 다시 실행해야 함).
예를 들면 :
COPY . /tmp/
를 앞에 둔 경우보다 RUN
단계에 대한 캐시 무효화가 더 적습니다.
이미지 크기가 중요하므로 ADD
를 사용하여 원격 URL에서 패키지를 가져 오는 것은 권장되지 않습니다. 대신 curl
또는 wget
을 사용해야 합니다.
이렇게하면 더 이상 필요하지 않은 파일을 추출한 후 삭제할 수 있으며 이미지에 다른 레이어를 추가 할 필요가 없습니다.
예를 들어 다음과 같은 행위는 피해야합니다.
대신 다음과 같이하십시오.
ADD
의 tar 자동 추출 기능이 필요하지 않은 다른 항목(파일, 디렉토리)의 경우 항상 COPY
를 사용해야합니다.
ENTRYPOINT
의 가장 좋은 용도는 이미지의 기본 명령을 설정하여 해당 이미지의 명령인 것처럼 실행되도록 허용하는 것입니다 (그런 다음 CMD
를 기본 플래그로 사용).
명령 줄 도구 's3cmd'에 대한 이미지의 예부터 시작하겠습니다.
이제 이미지를 다음과 같이 실행하여 명령의 도움말을 표시 할 수 있습니다.
또는 올바른 매개 변수를 사용하여 명령을 실행합니다.
이것은 위의 명령에 표시된대로 이미지 이름이 바이너리에 대한 참조로 두 배가 될 수 있기 때문에 유용합니다.
ENTRYPOINT
명령어는 도우미 스크립트와 함께 사용할 수도 있어, 도구를 시작하는데 두 단계 이상이 필요할 때도 위의 명령과 비슷한 방식으로 작동 할 수 있습니다.
앱을 PID 1로 구성
도우미 스크립트는 컨테이너에 복사되고 컨테이너 시작시 ENTRYPOINT
를 통해 실행됩니다.
이 스크립트를 통해 사용자는 여러 가지 방법으로 Postgres와 상호 작용할 수 있습니다.
간단히 Postgres를 시작할 수 있습니다.
또는 Postgres를 실행하고 매개 변수를 서버에 전달하는 데 사용할 수 있습니다.
마지막으로 Bash와 같은 완전히 다른 도구를 시작하는 데 사용할 수도 있습니다.
VOLUME
명령은 데이터베이스 저장소 영역, 구성 저장소 또는 Docker 컨테이너에서 생성 한 파일/폴더를 노출하는 데 사용해야합니다.
이미지의 변경 가능 하거나 사용자 서비스 가능 부분에 VOLUME
을 사용하는 것이 좋습니다.
권한없이 서비스를 실행할 수 있는 경우 USER
를 사용하여 루트가 아닌 사용자로 변경하십시오.
RUN groupadd -r postgres && useradd --no-log-init -r -g postgres postgres
와 같이 Dockerfile
에 사용자와 그룹을 생성하여 시작합니다.
명시적인 UID / GID 고려
이미지의 사용자 및 그룹에는 이미지 재 구축에 관계없이 "다음" UID/GID가 할당된다는 점에서 비 결정적 UID/GID가 할당됩니다. 따라서 중요한 경우 명시적인 UID/GID를 할당해야합니다.
마지막으로 레이어와 복잡성을 줄이려면 USER
를 자주 앞뒤로 전환하여 사용하지 마십시오.
명확성과 신뢰성을 위해 항상 WORKDIR
에 절대 경로를 사용해야합니다.
또한 읽기, 문제 해결, 유지 관리가 어려운 RUN cd… && do-something
과 같은 명령을 확산시키는 대신 WORKDIR
을 사용해야합니다.
ONBUILD
명령은 현재 Dockerfile
빌드가 완료된 후 실행됩니다.
ONBUILD
는 현재 이미지의 FROM
에서 파생 된 모든 하위 이미지에서 실행됩니다.
ONBUILD
명령을 부모 Dockerfile
이 하위 Dockerfile
에게 제공하는 명령으로 생각하십시오.
Docker 빌드는 하위 Dockerfile
의 명령보다 먼저 ONBUILD
명령을 실행합니다.
ONBUILD
로 빌드 된 이미지는 별도의 태그를 가져야합니다 (예 : ruby:1.9-onbuild
또는 ruby:2.0-onbuild
).
ONBUILD
에 ADD
또는 COPY
를 넣을 때 주의하세요.
새 빌드의 컨텍스트에 추가되는 리소스가 누락 된 경우 "onbuild" 이미지가 처참히 실패합니다.
위에서 권장했던로 별도의 태그를 추가하면 Dockerfile
작성자가 선택할 수 있도록하여 이를 완화하는 데 도움이됩니다.
이 공식 이미지에는 대표적인 Dockerfile
이 있습니다.
이러한 상태 비 저장 방식으로 컨테이너를 실행하는 동기에 대해 알아 보려면 "The Twelve-factor App" 방법론의 를 참조하세요.
이 섹션의 예제에서는 편의상 를 사용하지만 stdin
에 Dockerfile
을 제공하는 모든 방법을 사용할 수 있습니다. .
빌드 컨텍스트에서 some파일을 제외하여 빌드 속도를 높이려면 를 참조하세요.
아래 예제는 현재 디렉토리 (.
)를 빌드 컨텍스트로 사용하고 를 사용하여 stdin
을 통해 전달되는 Dockerfile
을 사용하여 이미지를 빌드합니다.
아래 예제는 stdin
의 Dockerfile
을 사용하여 이미지를 빌드하고 에서 hello.c
파일을 추가합니다.
소스 저장소를 재구성하지 않고 빌드와 관련이없는 파일을 제외하려면 .dockerignore
파일을 사용하십시오. 이 파일은 .gitignore
파일과 유사한 제외 패턴을 지원합니다. 생성에 대한 정보는 을 참조하십시오.
를 사용하면 중간 레이어 및 파일 수를 줄이기 위해 고민하지 않고 최종 이미지의 크기를 대폭 줄일 수 있습니다.
이미지는 빌드 프로세스의 마지막 단계에서 빌드되므로 을 통해 이미지 레이어를 최소화 할 수 있습니다.
각 컨테이너를 하나의 프로세스로 제한하는 것은 좋은 경험 규칙이지만 강력하고 빠른 규칙은 아닙니다. 예를 들어, 컨테이너는 을 할 수 있을 뿐만 아니라 일부 프로그램은 자체적으로 추가 프로세스를 생성 할 수 있습니다. 예를 들어 는 여러 작업자 프로세스를 생성 할 수 있고 는 요청 당 하나의 프로세스를 생성 할 수 있습니다.
컨테이너를 가능한 한 깨끗하고 모듈식으로 유지하기 위해 최선의 판단을 사용하십시오. 컨테이너가 서로 의존성이 있는 경우 를 사용하여 이러한 컨테이너가 통신 할 수 있는지 확인할 수 있습니다.
다음은 의 예입니다.
가능하면 현재 공식 이미지를 이미지의 기초로 사용하세요. 는 엄격하게 제어되고 크기가 작으며 (현재 5MB 미만) 전체 Linux 배포판이므로 권장합니다.
허용되는 레이블 키 및 값에 대한 지침은 를 참조하십시오. 레이블 쿼리에 대한 자세한 내용은 의 필터링 관련 항목을 참조하십시오. Dockerfile 참조의 도 참조하세요.
상위 이미지의 많은 "필수"패키지가 내에서 업그레이드 할 수 없으므로 RUN apt-get upgrade
및 dist-upgrade
를 피하십시오.
부모 이미지에 포함 된 패키지가 오래된 경우 해당 관리자에게 문의하십시오.
업데이트해야하는 특정 패키지 foo
가있는 경우 apt-get install -y foo
를 사용하여 자동으로 업데이트합니다.
공식 Debian 및 Ubuntu 이미지 이므로 명시 적으로 호출 할 필요가 없습니다.
대부분의 다른 경우 CMD
에는 bash, python 및 perl과 같은 대화 형 셸이 제공되어야합니다.
예로 : CMD ["perl", "-de0"]
, CMD ["python"]
또는 CMD ["php", "-a"]
.
이 형식을 사용하면 docker run -it python
과 같은 것을 실행할 때 사용할 수있는 쉘로 이동할 준비가 된 것입니다.
CMD
는 와 함께 CMD ["param", "param"]
방식으로 사용해서는 안 됩니다.
사용자는 사전에 ENTRYPOINT
의 작동 방식에 대해 잘 알고 있어야 합니다.
[ENV 명령어에 대한 Dockerfile 참조] ()
예를 들어 는 다음과 같은 스크립트를 ENTRYPOINT
로 사용한다.
이 스크립트는 을 사용하므로 최종 실행 애플리케이션이 컨테이너의 PID 1이 됩니다. 이를 통해 애플리케이션은 컨테이너로 전송 된 모든 Unix 신호를 수신 할 수 있습니다. 자세한 내용은 를 참조하세요.
Go 아카이브/tar 패키지의 빈약한 파일 관리에서 로 인해 Docker 컨테이너 내에 상당히 큰 UID를 가진 사용자를 만들려고하면 컨테이너 계층의 /var/log/faillog
가 NULL(\0) 문자로 채워집니다.
해결 방법은 --no-log-init
플래그를 useradd에 전달하는 것입니다.
Debian/Ubuntu adduser
명령어는 이 플래그를 지원하지 않습니다.
예측할 수없는 TTY 및 신호 전달 동작이 문제를 일으킬 수 있으므로 sudo
를 설치하거나 사용하지 마십시오.
root
가 아닌 사용자로 실행하지만 데몬을 root
로 초기화 하는 등 sudo
와 유사한 기능이 절대적으로 필요한 경우 사용을 고려하세요.
ONBUILD
는 주어진 이미지에서 FROM
으로 빌드 될 이미지에 유용합니다.
예를 들어 에서 볼 수 있듯이 Dockerfile
내에서 해당 언어로 작성된 임의 사용자 소프트웨어를 빌드하는 언어 스택 이미지에 ONBUILD
를 사용합니다.