ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Docker 이미지(Dockerfile)
    Container 2016. 3. 4. 09:00
    반응형

    Docker를 사용한다는건 지정된 Docker이미지를 이용해서 컨테이너를 실행한다는 것과 같다. 결국 이미지를 어떻게 설정할 수 있느냐가 docker를 사용하는데 중요한 요소가 된다. dockerDockerfile이라는 텍스트 파일을 이용해서 이미지를 사용자가 원하는대로 설정할 수 있게 한다. Dockerfile을 만든 후에는 docker build 명령을 이용해서 Dockerfile에 설정된대로 이미지를 빌드할 수 있다. 이때 빌드에서 제외할 파일들은 .dockerignore파일에 명시해서 빌드에 포함되지 않도록 제외할 수 있다.
    그럼 이제 Dockerfile 구조가 어떻게 되어 있는지 살펴보자.
    Dockerfile의 기본 구조는 명령어 인자의 형식으로 이루어져 있고, 이런 명령들이 순서대로 나열되어 있다. 이 때 각 명령어는 위에서 부터 순서대로 실행되고, 각각의 명령어들이 독립적으로 실행되서 다음에 실행되는 명령어에 영향을 미치지 않는다.
    파일내에서 주석을 선언하기 위해서는 #을 사용하면 된다. 그러면 # 뒤에 나오는 구문은 주석으로 인식되서 빌드할때 영향을 미치지 않게 된다.
    우선 다음과 같은 간단한 Dockerfile을 만들어 보자.
    FROM ubuntu:14.04
    COPY ./ /mydir
    이제 Dockerfile이 있는 디렉토리에서 빌드를 실행하려면 아래와 같이 하면 된다.
    docker build ./

    이 명령이 입력되면 docker는 현재 디렉토리에 Dockerfile이 있는지 확인한 다음에 그 Dockerfile을 이용해서 이미지를 빌드한다. 화면에 나오는 결과는 다음과 같다.

    Dockerfile에 있는 명령들이 순서대로 실행되고71bd0bbf8849라는 이미지 ID를 가진 이미지가 생성된 걸 알 수 있다. docker images 명령을 통해서 이미지를 확인할 수 있다.

    화면을 보면 저장소와 태그에 정보가 없는데 이미지를 빌드할때 –t 옵션을 주면 저장소 이름과 태그 정보까지 같이 생성할 수 있다.
    docker build -t dockerbook:stable  ./

    이렇게 하면 dockerbook이라는 저장소에 stable이라는 태그를 가진 이미지가 생성된 걸 확인할 수 있다.

     
    여기서 사용된 Dockerfile의 내용은 간단하다.
    FROM Ubuntu:14.04는 사용자 이미지를 빌드할 기본 이미지를 가르킨다. 여기서는 Ubuntu 14.04버전을 기본 이미지로 사용했다. 그리고COPY ./ /mydir 이 부분은 현재 디렉토리를 컨테이너의 /mydir로 복사하라는 명령이다.
    실제로 이 컨테이너를 실행한 다음에 /mydir 내용을 확인해 보면 현재 디렉토리에 있던 파일들이 컨테이너안에 들어와 있는 걸 확인할 수 있다.
     
    Dockerfile에서 사용할 수 있는 명령에는 어떤 것들이 있는지 좀 더 자세히 알아보자.
    명령어는 대소문자를 구분하지는 않지만 가독성 때문에 가급적 대문자를 사용하는 것이 권장되고 있다.
     
    FROM <이미지>
    FROM <이미지>:<태그>
    FROM <이미지>@<다이제스트>

    FROM 명령어는 Dockerfile에서 사용할 기본 이미지를 설정하는 명령이다. 주석과 공백을 제외하고는 항상 Dockerfile의 가장 처음에 와야하는 명령이다. 어떤 이미지를 사용할 것인지 알아야 그 이미지위에서 다른 명령들을 실행할 수 있기 때문이다. 명령어 중에 <태그> 부분은 생략할 수도 있는데, 그럴때는 기본으로 latest 태그에 해당하는 이미지를 사용한다. <다이제스트>는 이미지의 컨텐츠 기반 식별자인데, 태그와는 별도로 이 이미지의 내용이 변하지 않았다는걸 알수 있게 해준다. 이미지의 다이제스트 확인은docker images --digests 명령을 통해서 확인할 수 있다.
    Dockerfile 에서 이미지를 여러개 만들기 위해서  FROM이 여러번 올수도 있다. Docker에서는 가능하면 기본 이미지로 공식 저장소에 있는 이미지를 사용하길 권장한다. 그중에서도 데비안 이미지(https://hub.docker.com/_/debian/)를 추천하고 있다. 데비안 이미지는 최대한 작은 용량을 유지하도록 타이트 하게 관리되고 있다.
     
    MAINTAINER <name>

    이미지를 만든 사람이 누구인지 명시한다.
     
    RUN <명령어> - 셀 형식
    RUN [“executable”, “param1”, “param2”] – 명령어 형식

    현재 이미지의 최상단 레이어에서 <명령어>를 실행하고 docker 파일시스템에 결과를 커밋한다. 이렇게 커밋된 이미지는 Dockerfile의 다음 명령에 이용된다. 첫번째 형식에 있는 <명령어> 구문은 /bin/sh -c 명령을 이용해서 실행된다. 두번째 형식은 셀 문자열에 엉뚱한 값이 오지 않고 깔끔하게 필요한 인자들만 사용할 수 있게 해준다. 사용되는 셀도 /bin/sh가 아니라RUN ["/bin/bash", "-c", "echo", "Hello world"] 등의 형식을 이용하면 기본 셀이 아닌 다른 셀을 이용할수도 있다. 이때 인자값들은 JSON배열 형식으로 처리되기 때문에 쌍따옴표(“)를 써야한다는 것에 주의하자. 그냥 따옴표(‘)는 안된다. 셀 형식과 다르게 명령어 형식은 명령어 셀을 호출하는게 아니기 때문에 인자에 변수를 사용할 수 없다. RUN [ "echo", "$HOME" ] 이렇게 사용했을때 $HOME을 변수로 인식해서 값을 대입하지 않는다. 그냥 $HOME라는 문자열 자체를 출력해 버린다. $HOME을 변수로 인식하게 사용하려면 셀 형식을 사용하거나, RUN [ "sh", "-c", "echo", "$HOME" ] 처럼 직접 셀을 지정해 주어야 한다. RUN 명령은 기본적으로 캐시값을 저장하고 있다가 다음 빌드에 사용하는데, docker build --no-cache 이렇게 옵션을 줘서 캐시를 사용하지 않고 매번 새롭게 빌드하게 할 수 있다.
    RUN 명령어는 가독성을 좋게하고 나중에 관리하기 편하기 위해서 한줄로 길게 늘여 쓰기 보다는 \를 이용해서 여러줄로 늘여 쓰는 것이 좋다. 이를 위해 많이 사용되는 예제로 apt-get이 있다. apt-get의 경우 바로 apt-get install을 사용하면 저장소 정보가 업데이트 되어 있지 않아서 에러가 발생하는 경우가 종종 있다. 이럴때 apt-get update를 사용해 주어야 하는데, apt-get update후 따로 apt-get install을 하기 보다는 apt-get update && apt-get install 형태로 붙여서 쓸 수 있다. 또한 한번에 여러개의 패키지를 설치하기 위해서 \를 이용해서 여러개의 패키지를 한꺼번에 설치할 수 도 있다.
    RUN apt-get update && apt-get install –y \
        build-essential \
        git  \
        curl
     
    CMD ["executable","param1","param2"] – 명령어 형식
    CMD ["param1","param2"] – ENTRYPOINT의 기본 인자로서 사용
    CMD 명령어param1 param2 – 셀 형식

    컨테이너에서 실행할 명령어를 지정한다. 하나의 Dockerfile에서 한번만 사용할 수 있는 명령이고, CMD가 여러개 있을 경우에는 가장 마지막에 있는 CMD만 실행된다.
    CMD 명령의 목적은 컨테이너가 실행될 때, 내부에서 실행될 명령어를 지정하는데 있다. 셀 형식이 아닐때는 JSON 배열형식으로 인식하기 때문에 역시나 따옴표(“)를 이용해야 한다. RUN과 마찬가지로 명령어 셀을 호출하는 방식이 아니기 때문에 필요할때는 직접 셀을 지정해 주어야 한다. CMD 에서 실행되는 명령에 사용자가 옵션을 주고 싶으면 docker run 명령을 실행할때 옵션으로 인자들을 지정해 줄 수 있다. RUNCMD의 차이는 RUN은 이미지를 빌들할때 실행되고 그 결과를 이미지에 커밋해서 저장하는데, CMD는 이미지에 저장되는게 아니라 나중에 만들어진 이미지가 실행될때 컨테이너안에서 실행되는 명령이라는 것이다.
     
    LABEL
    LABEL <>=<> <>=<> …

    LABEL은 이미지에 메타데이터를 추가한다. LABEL값에 공백을 포함하려면 따옴표로 묶으면 된다. 줄바꿈을 넣으려면 백슬래시를 사용한다.
    LABEL “mystr” = “Hello World”
    이미지에 LABEL을 여러개 넣을 수 있는데 각각의 <>=<> 사이에 공백을 주면 된다. Docker에서는 가능하면 LABEL을 하나만 사용하길 권장한다. 여러개의 LABEL 명령어를 사용하면 각 LABEL명령어마다 레이어가 추가되기 때문이다. 아래처럼 한줄에 붙여서 여러개의 LABEL을 입력한다 하더라도 다른 명령어와는 다르게 각각의 LABEL마다 이미지 레이어가 생성된다.
    LABEL label1=”value1” label2=”value2”
    시스템에 중복되는 키값이 있으면 나중에 오는 키값이 이전 키값을 덮어쓰게 된다.
    docker inspect 이미지 or 컨테이너 명령을 이용하면Config=>Labels 항목에 이미지나 컨터이너에 설정된 LABEL을 확인할 수 있다.
     

    EXPOSE <port> [<port>...]

    컨테이너가 실행중에 외부에 노출되는 포트를 나타낸다.
    이때 포트는 컨테이너가 실행되는 호스트의 포트가 아니라 컨테이너의 포트를 의미한다. EXPOSE에 명시된 컨테이너의 포트와 호스트상의 임의의 포트가 연결되어서 외부에서 컨테이너에 접근할 수 있게 된다. 호스트에서 어떤 포트를 사용할 것인지를 EXPOSE에서 두번째 port값을 명시해서 지정할 수도 있는데 권장되지는 않는 방법이다. 호스트에 컨테이너가 하나만 사용되는 것도 아닐 것이고 굳이 컨테이너가 아니더라도 호스트에서 해당 포트를 이미 사용중일수도 있기 때문이다. Docker 이미지를 실행할때 –p 옵션을 이용해서 컨테이너의 포트와 호스트의 포트를 명시해서 지정할수 있다. 만약 하나의 호스트에 여러개의 Docker 컨테이너가 실행하게 된다면 이 EXPOSE에 명시된 포트를 통해서 서로 통신하게 된다.
     
     
    ENV <key> <value>
    ENV <key>=<value>

    Dockerfile안에서 사용할 환경변수를 지정한다. 그리고 이 Dockerfile을 이용해서 만들어진 이미지 파일안에서도 이 값을 환경변수로 사용할 수 있다. docker inspect를 이용하면 Config=>Env 항목에 여기 있는 값이 적용되있는 걸 볼 수 있다. 환경변수 <key>에 값인 <value>를 할당한다. Dockerfile안에서 환경변수를 사용할 수 있는 명령어는ENV, ADD, COPY, WORKDIR, EXPOSE, VOLUME, USER 등이다. 사용하는 방법은 ‘$변수명’, ‘${변수명}’ 형식으로 사용한다. 표준 배시셀과 비슷하게 사용할 수 있다. ${variable:-word}라고 사용하면 variable이 설정되어 있으면 variable에 설정된 값을 사용하고, variable이 없으면 word를 사용한다. ${variable:+word}라고 사용하면 variable이 설정되어 있으면 word값을 사용하고 variable이 설정되어 있지 않으면 빈 문자열을 사용한다. 이 경우에는 variable의 값이 직접 사용되지는 않는다.
     환경변수를 여러개 선언할때는
    ENV key1=”value 01”  key1=”value 02“
    또는
    ENV key1=”value 01” 
    ENV key1=”value 02“
    이렇게 2가지 방식을 사용할 수 있는데 두번째 방식을 사용했을때는 각 ENV 명령마다 이미지에 레이어가 하나씩 추가되기 때문에 레이어 개수를 줄이기 위해서는 첫번째 방식이 좋다.
     
     
    ADD <src>... <dest>
    ADD [“<src>”, … “<dest>”]

    <src>에 있는 파일, 디렉토리, 원격 URL에 있는 파일등을 <dest>에 명시된 컨테이너의 파일시스템으로 복사한다. <src>docker build 에서 명시한 경로의 하위여야 한다. <src>에는 와일드카드나Docker 자체가 Go 언어로 개발되었기 때문에 Go 언어의filepath.Match함수에 있는 규칙을 만족하는 패턴을 사용할 수 있다. 여기에 맞는 패턴은 다음과 같다.
    * : 길이에 상관없이 모든 문자열이 올 수 있다.
    ? : 임의의 문자 하나가 올 수 있다.
    [ [ '^' ] { 문자범위 } ] : 여러가지 문자타입을 지어할 수 있다. 비어있는 문자열은 안된다.
    • 문자범위 : c(\\, -, ] 등은 안된다.), \\c, 낮은문자-높은문자(a-z 이런식으로 a부터 z까지의 문자가 올수 있다는 걸 의미한다.)
    c : 문자 c 맞는지 확인한다. 이때 c*, ?, \\, [ 등은 아니다.
    \\c : c 문자 c가 맞는지 확인한다.
    위 패턴들을 이용해서 아래처럼 실제 ADD 명령에서 사용할 수 있다.
    ADD home* /mydir/      # home으로 시작하는 모든 파일들을 추가한다.
    ADD hom?.txt /mydir/   # homa.txt, home.txt?에 맞는 모든 파일들을 추가한다.
     
    <dest>는 절대경로이거나 WORKDIR의 상대경로여야 한다. 새로 생성되는 모든 파일과 디렉토리는 GIDUID값이 0이다. <src>가 원격 파일의 URL일때는 생성되는 파일의 퍼미션은 600이 된다. 원격파일의 http 헤더에Last-Modified 값이 있으면 그 값은 생성되는 파일의 mtime 값이 된다. 그외의 경우에는 ADD 명령어에 의해 처리된 다른 파일들은 mtime값이 있더라도 그 값이 파일이 변경되었단는걸 알려주는 정보가 되지는 않는다.
    docker 빌드를 할때 Dockerfile을 현재 디렉토리에 있는걸 사용하는게아니라 docker build - < dockerfile 이런식으로 표준입력을 통해서 입력할수도 있는데, 이때는 빌드컨텍스트가 없기 때문에 이 DockerfileURL기반의 ADD 명령어만 처리할 수 있다. 그리고docker build - < archive.tar.gz 이런식으로 Dockerfile을 가지고 있는 압축된 파일을 빌드하라고 명령을 실행할수도 있는데, 이때는 Dockerfile이 압축된 파일의 루트에 있어야 하고, 그 루트경로가 Dockerfile이 실행되는 컨텍스트가 된다. ADD 명령은 인증이 필요한 URL파일은 처리하지 못한다. 인증이 필요한 외부 URL에 있는 파일들은 RUN wget이나 RUN curl명령을 이용해서 받아오면 된다.  Dockerfile을 빌드하다가 ADD 명령어가 나오면 그때까지 있던 캐시를 초기화한다.
    ADD 명령이 파일을 복사할때는 아래 규칙들을 따른다.
    • <src>경로는 빌드 컨텍스트에 포함되어 있어야 한다. ADD ../file.txt /file 처럼 빌드 컨텍스트를 벗어나는 경로를 지정할 수는 없다. docker build명령의 첫번째 단계에서 컨텍스트 디렉토리와 하위디렉토리들을 docker 데몬으로 복사하기 때문에 컨텍스트를 벗어나는 파일들은 사용할 수 없다.
    • <src>URL이고 <dest>/로 끝나지 않으면 URL에 있는 파일을 다운받아서 <dest>로 복사한다.
    • <src>URL이고 <dest>/로 끝나면 URL에 있는 파일을 다운받아서 <dest>/<filename>으로 복사한다.
    • <src>가 디렉토리면 메타데이터를 포함한 디렉토리내의 모든 컨텐츠가 복사된다. 이때 <src>디렉토리 자체는 복사되지 않고 <src>내부의 컨텐츠들만 복사된다.
    • <src>가 로컬에 있는 압축파일(gzip, bzip2, xz 형식 등)이면 디렉토리 형식으로 압축이 풀려서 복사된다. <src>가 외부 URL에 있는 압축파일이면 압축이 풀리지 않고 압축된 파일 그대로 복사된다.
    • <src>가 여러개 명시되거나 와일드카드를 사용하려면 <dest>는 디렉토리이거나 /로 끝나야 한다.
    • <dest>/로 끝나지 않으면 <dest>를 파일로 간주해서 <src>의 내용이 <dest> 써진다.
    • <dest>가 존재하지 않으면, <dest>가 새로 만들어 진다. 이때, <dest>에 필요한 중간 경로들이 없다면 그 경로들도 모두 같이 만들어 진다.
     
     
     
    COPY <src>... <dest>
    COPY ["<src>",... "<dest>"]

    <src>에 있는 파일이나 디렉토리를 컨테이너의 <dest> 경로에 복사한다.
    <src>docker build 에서 명시한 경로의 하위여야 하고 <dest>는 절대경로이거나 WORKDIR의 하위경로여야 한다. ADD와는 원격 URL을 직접 다운로드 하지 않는 다는 것만 다르고 거의 유사하게 작동한다. 앞에 나온 COPYADD는 거의 비슷하게 동작하는데, docker에서는 COPYADD를 용도별로 구분해서 사용하는걸 권장한다. ADDCOPY의 기능을 포함하고 있기는 하지만 단순히 파일이나 디렉토리를 이미지로 복사할때는 COPY를 사용하는게 더 좋다. 사용하기가 직관적이기 때문이다. ADD는 로컬에 있는 tar 파일을 이미지에 압축을 풀어서 넣을때 사용하는게 좋다. 그리고 ADD가 원격 URL에 있는 파일을 이미지로 복사해 오는 기능을 지원하기는 하지만 이미지 용량을 생각했을때는 RUN 명령어에서 curl이나 wget을 이용해서 가져오는 것이 더 좋다. 이렇게 받아오면 파이프라인을 통해서 받은 파일의 압축을 풀거나 하는 동작을 하나의 명령에서 처리할 수 있어 이미지 레이어가 줄어들게 된다.
     

    ENTRYPOINT ["executable", "param1", "param2"] – 명령어 형식
    ENTRYPOINT command param1 param2 – 셀 형식
    ENTRYPOINT를 이용해서 컨테이너를 실행가능한 형태로 만들수 있다. docker run을 해서 선택한 이미지에서 지정한 프로세스를 실행할 수 있다는 뜻이다.
    아래 명령을 이용해서 간단하게 nginx를 띄울 수 있다.
    docker run -i -t --rm -p 80:80 nginx
    Dockerfile에 있는 ENTRYPOINT 명령 말고, 이미지를 실행할때 entrypoint를 지정하고 싶으면 docker run –entrypoint 를 통해서 실행하면 된다.
    셀 형식을 사용하면 CMDrun 명령어의 인자보다 우선해서 실행되지만 /bin/sh –c 의 하위 명령으로 실행된다. 이렇게되면 시스템 신호를 받지 못한다. 이게 무슨 의미냐면 실행될때 컨테이너의 PID 1 로 실행되지 않아서 유닉스 신호를 받지 못한다는 것이다. docker stop <컨테이너명> 같은 명령을 실행했을때 컨테이너안의 프로세스가 SIGTERM을 받지 못한다는 것이다.
    명령어 형식을 사용하면 실행되는 프로세스의 PID1인걸 확인할 수 있다.
    아래처럼 간단한 Dockerfile을 이용해서 이미지를 만든다음에 확인해 보자.
    FROM ubuntu:14.04
    ENTRYPOINT ["top", "-b"]


    docker build -t top .
    docker run -it --rm --name test top

    컨테이너 안에서 top 명령이 PID 1로 실행되는걸 확인할 수 있다.

     
    컨테이너 내의 프로세스 상황을 더 자세히 보고 싶으면 위 명령어가 실행된 상태에서  다른 창을 열고 아래 명령을 실행시키면 된다.
    docker exec -it test ps aux

     
    실행된 컨테이너를 중지 시키고 싶으면 docker stop test를 입력하면 된다.
     
    셀 형식에서는 어떻게 되는지 확인하기 위해 아래와 같이 Dockerfile을 수정한 다음에 테스트 해보자.
    FROM ubuntu:14.04
    ENTRYPOINT top –b
     
    빌드하고 실행시켜보면 결과가 다르게 나오는걸 확인할 수 있다.
    docker build -t top .
    docker run -it --rm --name test top

    PID 1sh프로세스이고 top 프로세스의 PID6이다.
     
    명령어 형식과 동일하게 다음 명령으로 컨테이너 내부의 프로세스 상태를 확인해 보자.
    docker exec -it test ps aux

     
    ENTRYPOINT에서 지정한 명령이 /bin/sh –c의 하위명령어로 실행된걸 확인할 수 있다. docker stop test를 입력해도 프로세스가 SIGTERM명령을 받지 못하기 때문에 여러번 시도하다가 결국 SIGKILL을 통해서 중지된다.
    셀형식에서는 이렇게 PID1이 아니게 하려면 아래처럼 ENTRYPOINTexec를 명시해 주면 된다.
    ENTRYPOINT exec top –b
     
     
    VOLUME ["/data"]
    지정된 이름으로 마운트 지점을 생성한다. JSON 배열 형식으로 선언할수도 있고, VOLUME /var/log /var/db처럼 일반 문자열 형식으로 여러 경로를 지정할수도 있다.
    주로 이미지 밖에 있으면서 데이터에 변경이 일어날 수 있는 부분을 VOLUME을 이용해서 마운트해서 사용한다.
     
    USER daemon
    이미지를 실행할때 사용할 사용자명이나 UID를 지정한다. RUN, CMD, ENTRYPOINT명령어에도 적용된다.
     

    WORKDIR /path/to/workdir
    RUN, CMD, ENTRYPOINT, COPY, ADD 명령어가 실행되는 작업 디렉토리를 설정한다. Dockerfile안에서 여러번 사용되면 직전에 사용됐던 WORKDIR을 기준으로 상대경로로 이동한다.
     

    ONBUILD [INSTRUCTION]
    현재 이미지가 나중에 다른 빌드의 기본 이미지로 사용될때, 그때 이 이미지에 실행될 트리거 명령을 추가한다. ONBUILD가 있는 이미지를 다른 이미지에서 사용하면 그 이미지가 빌드될때 ONBUILD에 있는 명령어가 실행된다는 의미다. 다른 이미지의 기본 이미지를 만들때 유용하게 사용할 수 있는 명령이다. 예를 들어 독자가 사용자의 파이썬 애플리케이션을 실행하는 이미지를 만든다고 생각해보자. 독자가 이미지를 만드는 시점에는 사용자의 소스코드가 특정 디렉토리에 들어가게 할 수 없다. ONBUILD를 이용하면 사용자가 독자의 이미지를 이용해서 다시 도커 이미지를 빌드할 때 사용자의 소스를 독자가 원하는 위치에 복사해 넣을 수 있다. ONBUILD ONBUILD 처럼 ONBUILD에서 다시 ONBUILD를 사용할 수 없고, FROM이나 MAINTAINER등은 ONBUILD에서 사용할 수 없다.
     
    .dockerignore 파일
    Dockerfile의 빌드 과정중에서 포함되지 않았으면 하는 파일들을 .dockerignore파일을 이용해서 지정할 수 있다. 예를 들어 빌드된 이미지 안에 Dockerfile 자체는 포함하고 싶지 않다거나 개발중이던 테스트 디렉토리를 포함하지 않는다거나 할 수 있다. .dockerignore파일은 docker 이미지가 빌드되는 경로의 루트에 있어야 한다. 다른 경로에 있게되면 그냥 일반 파일과 같이 취급된다. Go 언어의filepath.Match함수에 있는 규칙을 만족하는 패턴을 사용할 수 있다. 정규표현식은 지원하지 않는다. 다음 예제를 보자
    */temp*
    */*/temp*
    temp?
    *.md
     
    위에서 부터 순서대로 적용되면서 내려간다.
    */temp*  temp로 시작하는 모든 하위 디렉토리와 파일이 제외된다.
    */*/temp* 2단계 밑의 모든 하위디렉토리와 파일중 temp로 시작하는 것들이 제외된다.
    temp? 루트 디렉토리에 있는 파일중 tempa, tempbtemp뒤에 문자 하나가 오는 모든 파일이 제외된다.
    *.md 루트 디렉토리에 있는 모든 마크다운확장자(.md)를 가진 파일들이 제외된다.
    !LICENSE.md 위에서 제외된 마크다운 파일들 중에서 LICENSE.md는 제외해서 빌드할때 포함되게 한다. ! 기호를 이용해서 다시 예외처리를 할 수 있는 것이다. 이때 !를 사용하는 순서가 중요하다.
    *.md
    이렇게 순서가 뒤바뀌어 있다면 LICENSE.md에 대한 예외처리를 하기는 했지만 그 밑에서 *.md가 그 내용을 덮어써서 모든 마크다운 파일을 제외시켜 버리기 때문에 LICENSE.md가 빌드할때 빠지게 된다.
     
    Dockerfiles 만들때 유의할 점
    이미지가 하는 역할이 단순해야 한다. 컨테이너 하나가 하나의 프로세스라고 생각하면 된다. 웹서버 역할을 하는 컨테이너면 웹서버 만을 가지고 있어야하고, 그 안에 캐시라던가 DB같은 불필요한 서비스들을 가지고 있을 필요가 없다. 캐시나 DB가 필요하다면 따로 캐시용 컨테이너, DB용 컨테이너를 만들어서 띄우면 된다. 이렇게 컨테이너당 프로세스를 하나만 띄우도록 해 놓으면 나중에 확장하거나 컨테이너를 재사용하기가 편해진다. Dockerfiles을 만들때 이미지에 불필요한 패키지가 포함되지 않게 해야한다. 필요하지 않은 패키지를 포함해서 복잡도, 의존성, 이미지 크기를 늘리지 않도록 신경써야 한다. 그리고 이미지에서 사용하는 레이어를 가능한 줄이는 것이 좋다. 레이어가 많으면 용량도 커지고 배포할때도 느리다. 레이어를 줄이기 위해서 동일한 명령어를 여러번 사용하기 보다는 하나의 명령으로 줄여서 사용하는 것이 좋다.
    RUN apt-get update
    RUN apt-get install –y git
    RUN apt-get install –y subversion

    이렇게 사용하기 보다는 아래처럼 한줄로 줄이는 것이 좋다.
    RUN apt-get update && apt-get install –y git subversion

     
    반응형

    'Container' 카테고리의 다른 글

    Docker Machine  (0) 2016.03.11
    Docker Kitematic  (0) 2016.03.09
    Docker Compose  (0) 2016.03.07
    Docker 사용하기  (0) 2016.03.02
    Docker 설치하기  (0) 2016.03.02

    댓글

Designed by Tistory.