Dockerfile
이미지 생성하는 방법
- 아무것도 존재하지 않는 이미지를 생성(우분투, 센트os등등)을 생성
- 애플리케이션을 위한 환경을 설치하고 소스코드등을 복사해 잘 동작하는 것을 확인
- 컨테이너를 이미지로 커밋
위와같은 플로우대로 이미지를 만들어 개발중인 애플리케이션을 배포하면 해당 이미지는 매번 수작업으로 패키지를 설치하고 소스코드를 깃에서 복제하거나 호스트에서 복사해야합니다. 물론 직접 컨테이너에서 애플리케이션을 구동해 보고 이미지로 커밋하기 때문에 이미지의 동작을 보장할 수 있다는 점도 있습니다.
도커에서는 위와같은 일련의 과정을 손쉽게 기록하고 수행할 수 있는 빌드 명령어를 제공합니다. 완성된 이미지를 생성하기 위해 컨테이너에 설치해야 하는 패키지, 추가해야하는 소스코드, 실행해야 하는 명령어와 셸 스크립트 등을 하나의파일에 기록해 두면 도커는 이파일을 읽어 컨테이너에서 작업을 수행한 뒤 이미지로 만들어 냅니다.
이러한 작업을 기록한 파일의 이름을 Dockerfile이라 하며, 빌드 명령어는 Dockerfile을 읽어 이미지를 생성합니다. Dockerfile을 사용하면 직접 컨테이너를 생성하고 이미지르 커밋해야 하는 번거로움을 덜 수 있을 뿐더러 깃과 같은 개발도구를 통해 애플리케이션 빌드 및 배포를 자동화 할수 있다는 장점이 있습니다.
Dockerfile 작성
기본 개념은 Dockerfile은 컨테이너에서 수행해야 할 작업을 명시해야합니다. 그리고 도커엔진은 기본적으로 도커파일을 찾을때 해당 위치에 있는 Dockerfile이라는 이름을가진 파일일을 먼저 찾아가는 규칙이 있다는 점 입니다. 다른이름으로 Dockerfile을 작성할시 옵션으로 명시해 줘야합니다.
예시 Dockerfile
FROM ubuntu:14.04
MAINTAINER alicekl06
LABEL "purpose*-"practice"
RUN apt-get update
RUN apt-get install apach2 -y
ADD test.htm l /var/www/html
WORKDIR /var/www/html
RUN ["/bin/bash", "-c", "echo hello » test2.html"] EXPOSE 80
CMD apachectl -DF0RE6R0UND
명령어는 일반적으로 대문자로 표기합니다.
명령어 설명
- FROM:생성할 이미지의베이스가 될 이미지를 뜻합니다.FROM명령어는 Dockerfile을 작성할때 반드시 한번이상 입력해야 하며, 이미지 이름의 포맷은 docker run 명령어에서 이미지 이름을 사용했을 때와 같습니다. 사용하려는 이미지가 도커에 없다면 자동으로 pull합니다.
- MAINTAINER: 이미자를 생성한개발자의 정보를 나타냅니다. 일반적으로 Dockerfile을 작성한 시람과 연락할수있는 이메일 등을 입력합니다. 단, MAINTAINER는 도커 1.13.0 버전 이후로 사용하지 않습니다. 대신 MAINTAINER는 아래와 같은 LABELS. 교체해 표현할 수 있습니다.
LABEL maintainer "연락처~"
- LABEL: 이미지에 메타데이터를 추가합니다. 메타데이터는 ‘키:값’의 형태로 저장되며,여러 개의 메타데이터가 저장될 수 있습니다. 추가된 메타데이터는 docker inspect 명령어로 이미지의 정보를 구해서 확인할 수 있습니다.
- RUN:이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행합니다. 예제에서는 apt~get update와 aptᅳget install apache2 명령어를 실행하기 때문에 아파치 웹 서버가 설치된 이미지가 생성됩니다. 단, Dockerfile을 이미지로 빌드하는 과정에서는 별도의 입력이 불가능하기 때문에 aptᅳget install apache2 명령어에서 설치할 것일지를 선택하는 丫/N을 Yes 로 설정해야 합니다. 이미지를 빌드할 때 별도의 입력을 받이야 하는 RUN이 있다면 build 명령어는 이를 오류로 간주하고 빌드를 종료합니다.
- ADD:파일을 이미지에 추가합니다. 추가하는 파일은 DockerfileO| 위치한 디렉터리인 컨텍스트(Context)에서 가져옵니다. 컨텍스트에 대한 설명은 뒤의 2.4.3.2절 ‘‘이미지 빌드 과정 살펴보기"에서 다시 하겠지만 지금은 Dockerfile이 위치한 디렉터리에서 파일을 가져온다고 이해하면 됩니다. 예제에서는 Dockerfile이 위치한 디렉터리에서 test.html 파일을 이미지의 /var/www/html 디렉터리에 추가합니다.
JSON형태로도 작성할 수 있으며 그렇게 작성하게 되면 배열의 마지막 원소가 컨테이너에 추가될 위치입니다. - WORKDIR:명령어를 실행할 디렉터리를 나타냅니다. 배시 셸에서 cd 명령어를 입력하는 것과 같은 기능을 합니다. 예를 들어, WORKDIR /var/www/html이 실행되고 나서 RUN touch test를 실행하면 /var/www/html/ 디렉터리에 test 파일이 생성됩니다.
- EXPOSE:Dockerfile의 빌드로 생성된 이미지에서 노출할 포트를 설정합니다. 그러나 EXPOSE를 설정한 이미지로 컨테이 너를 생성했다고 해서 반드시 이 포트가 호스트의 포트와 바인딩되는 것은 아니며, 단지 컨테이너의 80번 포트를 시용할 것 임을 나타내는 것 뿐입니다. EXPOSE는 컨테이너를 생성하는 run 명령어에서 모든 노출된 컨테이너의 포트를 호스트에 Publish하는 -P 플래그(flag)와함께 사용됩니다.
- CMD: CMD는 컨테이너가 시작될때마다 실행할명령어(커맨드)를 설정하며, Dockerfile에서 한번만 사용할수 있습니다. Dockerfile에 CMD를 명시함으로써 이미지에 apachectl ᅳDFOREGRᄋUND라는 커맨드를 내장하면 컨테이너를 생성할 때 별도의 커맨드를 입력하지 않아도 이미지에 내장된 apachectl -DFOREGROUND 커맨드가 적용되어 컨테이너가 시작 될 때 자동으로 아파치 웹 서버가 실행될 것입니다. 그리고 아파치 웹 서버는 하나의 터미널을 차지하는 포그라운드 모드로 실행되기때문에 -d 옵션을 사용해 detached 모드로 컨테이너를 생성해야합니다.
Dockerfile 빌드
Dockerfile로 이미지 생성하기
dockerfile을 작성후 이미지를 만들기위해선 build명령어를 이해해야 합니다.
docker build - t mybuild:0.0 ./
- -t : 생성될 이미지의 이름 설정
그리고 마지막에 ./ 를 사용하는것은 현제 위치에 Dockerfile이 있으니 도커 엔진보고 해당 위치에 있는 Dockerfile을 읽어서 이미지를 만들어라~!!! 하는것입니다.(Dockerfile저장경로)
docker run -d -P --name myserver mybuild:O.0
- -P : EXPOSE에서 설정한 모든 포트를 호스트에 연결하도록 합니다. 이때 호스트에서 사용가능한 포트에 차례로 연결하므로 이 컨테이너가 호스트의 어떤 포트와 연결됐는지 확인할 필요가 있습니다.
docker port 컨테이너이름
빌드 과정 정리
- 빌드 컨텍스트
이미지 빌드를 시작하면 도커는 가장 먼저 빌드 컨텍스트를 읽어 들입니다. 빌드 컨텍스트는 이미지를 생성하는 데 필요한 각정 파일, 소스코드, 메타데이터 등을 담고 있는 디렉터리를 의미하며, Dockerfile이 위치한 디렉터리가 빌드 컨텍스트가 됩니다.
빌드 컨텍스트는 Dockerfile에서 빌드될 이미지에 파일을 추가할 때 사용됩니다. Dockerfile에서 이미지에 파일을 추가하는 방법은 앞에서 설명한 ADD 외에도 COPY가 있는데, 이 명령어들은 빌드 컨텍스트의 파일을 이미지에 추가합니다.
컨텍스트에 대한 정보는 이미지를 빌드할 때 출력된 내용 중 맨 위에 위치합니다.
컨텍스트는 build 명령어의 맨 마지막에 지정된 위치에 있는 파일을 전부 포함합니다. 깃과 같은 외부 URL에서 Dockerfile을 읽어 들인다면 해당 저장소에 있는 파일과 서브 모듈을 포함합니다.그렇기때문에 Dockerfile이 있는곳엔 이미지 빌드에 필요한 파일만 있는 것이 바람직합니다. 루트에 이미지 빌드하지 않도록 주의해야 하며 컨텍스트는 단순 파일뿐 아니라 하위 디렉터리도 전부 포함하게 되므로 빌드에 불필요한 파일이 포함된다면 빌드 속도가 느려질 뿐더러 호스트의 메모리를 지나치게 점유할 수도 있습니다. 이를 방지하기위해 .dockeringore라는 파일을 작성하면 빌드시 이파일에 명시된 이름의파일은 컨텍스트에서 제외합니다.
빌드 캐시를 사용하고 싶지 않을때
docker에서는 이미 한번 빌드된 이미지를 제빌드할때 캐시를해서 더 빠르게 빌드를 할 수 있는데 이는 때로는 필요하지 않은 기능이 될 수도 있습니다 가령 소스코드를 수정해서 제배포를 해야한다거나할 때입니다.
이때는 build명령어에 --no-cache옵션을 추가합니다.
반대로 캐시로 사용할 이미지를 직접지정할때는 -cache-from 이미지명 으로 사용할 수 있습니다.
기타 Dockerfile 명령어
- ENV - Dockerfile에서 사용될 환경변수를 저장합니다 설정한 변수는 ${} 를 통해 사용할 수 있습니다.
- VOLUME: 빌드된 이미지로 컨테이너를 생성했을때 호스트와 공유할 컨테이너 내부의 디렉터리를 설정합니다.
JSON 배열 형태로 여러개를 작성하거나 그냥 /test 와같이 컨테이너 내부의 경로를명시해서 사용할 수 있습니다. - USER : USER로 컨테이너 내에서 사용될 사용자 계정의 이름이나 UID를 설정하면 그 아래의 명령어는 사용자 권한으로 실행됩니다.
하지만 일반적으로 컨테이너 내부에서는 root 를 사용하도록 돼 있습니다. 이는 보안에 좋지 않기때문에 컨테이너를 최종 배포시엔 새로운 user를 만드는것이 좋습니다.
ENTRYPOINT 와 CMD 의 차이점
두 명령어다 컨테이너가 시작될 때 수행할 명령을 지정한다는 점에서 같습니다. 그러나 entrypoint는 커멘드를 인자로 받아 사용할 수 있는 스크립트의 역할을 할 수 있다는점에서 다릅니다.
entrypoint가 설정되지 않았다면 cmd에 설정된 명령어를 그대로 실행하지만 Entrypoint가 설정됐다면 cmd는 단지 entrypoint에 대한 인지의 기능을 합니다.
RUN하나당 하나의 이미지 레이어가 된다.
이점을 잘생각하면 Dockerfile을 작성할때 좀더 효율적인 이미지를 만드는대에 도움이 됩니다. && 을통해서 이미지레이어를 줄일수 도 있고 RUN명령어로 파일을 만들고 용량을 줄이기 위해 마지막에 삭제를 한다고 해도 이미 레이어에 처음 RUN 명령어로 만들었던 파일이 남아있기때문에 불필요하게 이미지의 크기가 커지는것을 하나의 명령으로 통일함으로써 해결할 수 있습니다.
출처 : 시작하세요 도커-쿠버네티스
'Docker' 카테고리의 다른 글
도커 엔진 기본 개념 (0) | 2023.08.07 |
---|---|
도커 이미지 기본개념 (0) | 2023.08.07 |
도커 데몬 (0) | 2023.05.31 |
docker/ expose 와 port 의 차이점 (0) | 2023.05.31 |
도커 스웜 개념 (0) | 2023.05.31 |