Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

DockerFile

Dockerfile에는 도커이미지를 빌드하기 위한 정보들이 들어 있다. 이 정보들을 이용해서 도커 이미지를 만들 수 있다.

DockerFile로 부터 이미지 만들기

docker build 명령을 실행하면 Dockerfile에 있는 정보들을 이용해서 도커 이미지 파일을 생성한다. build 명령 다음에 Dockerfile이 있는 디렉토리를 설정하면 된다. 만약 현재 디렉토리에 Dockerfile이 있다면 아래와 같이 하면 된다.
# docker build ./

-t를 이용해서 이미지를 태깅 할 수 있다. 도커 이미지가 성공적으로 빌드 되면, 태그도 함께 저장된다.
$ docker build -t myapp/joinc .
하나의 이미지에 대해서 2개 이상의 태그를 붙일 수 있다.
$ docker build -t myapp/joinc:1.0.2 -t myapp/joinc:lastest . 

이렇게 태깅된 정보는 docker images 명령으로 확인 할 수 있다.
$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
myapp/joinc                    1.0.2               91874953ae88        22 seconds ago      272.3 MB
이제 docker build 명령을 실행하면, 도커 데몬은 Dockerfile의 내용을 한줄씩 실행해서 그 결과를 새 이미지로 commit 하며, 최종적으로 새로운 이미지 ID를 출력한다.

가능하다면, 도커는 중간 이미지를 캐시형태로 저장해서, 도커 빌드 속도를 높인다. 동일한 베이스 이미지를 이용할 경우, 처음 이미지에만 시간이 좀 걸리고, 나머지는 매우 빠르게 만들어질 것이다.
$ docker build -t svendowideit/ambassador .
Sending build context to Docker daemon 15.36 kB
Step 1/4 : FROM alpine:3.2
 ---> 31f630c65071
Step 2/4 : MAINTAINER SvenDowideit@home.org.au
 ---> Using cache
 ---> 2a1c91448f5f
Step 3/4 : RUN apk update &&      apk add socat &&        rm -r /var/cache/
 ---> Using cache
 ---> 21ed6e7fbb73
Step 4/4 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh
 ---> Using cache
 ---> 7ea8aef582cc
Successfully built 7ea8aef582cc

형식

Dockerfile의 형식은 아래와 같다.
# Comment
INSTRUCTION arguments
Insruction은 대소문자 구분없이 사용할 수 있다. 명령과 옵션의 구분을 더 명확히 하기 위해서 일반적으로 대문자를 사용한다.

도커는 Dockerfile을 읽어서 instruction이 지시하는 내용을 실행한다. Dockerfile의 가장 처음에는 반드시 FROM이 와야 한다. 이 지시어는 새로운 이미지를 만들기 위한 Base Image를 설정하기 위해서 사용한다. 예를 들어 ubuntu를 베이스 이미지로 하고 싶다면 FROM ubuntu라고 명시해야 한다.

#은 주석이다. 주석 표시된 영역은 해석하지 않고 넘어간다.

Envirionment Replacement

환경 변수는 ENV로 설정할 수 있다. 이것은 Dockerfile 에서 일종의 변수처럼 사용 할 수 있다. ENV로 설정한 변수는 Dockerfile 에서 $variable_name이나 ${variable_name}과 같이 사용할 수 있다.
FROM busybox
ENV foo /bar
WORKDIR ${foo}
ADD . $foo
COPY \$foo /quux
ENV는 아래 instruction 에서 사용 할 수 있다.
  • ADD
  • COPY
  • ENV
  • EXPOSE
  • LABEL
  • USER
  • WORKDIR
  • VOLUME
  • STOPSIGNAL

FROM

베이스 이미지를 설정한다.
FROM <image>
혹은
FROM <image>:<tag>
FROM은 베이스 이미지(Base image)를 설정하기 위해서 사용한다. 도커 데몬은 여기에 설정된 이미지로 부터 새로운 이미지를 만든다. 만약 로컬에 베이스 이미지가 없다면, 이미지 저장소로 부터 풀링한다. FROM은 반드시 Dockerfile의 첫 줄에 와야 한다. tag는 옵션이다. tag를 생략하면 latest를 가져온다.

MAINTAINER

이미지를 만든 사람의 정보를 알려주기 위해서 사용한다.

RUN

RUN은 두 개의 폼을 가진다.
  • RUN <command> : command는 쉘(/bin/sh -c)로 실행된다.
  • RUN ["executable", "param1", "param2"] (exec form)
RUN은 현재 이미지 위에서 새로운 레이어의 명령을 실행하고 그 결과를 커밋한다. 따라서 실행 결과는 새로만든 이미지에서 사용 할 수 있게된다. RUN은 역실래쉬(\)를 이용해서 여러 줄에 걸쳐서 명령을 실행 할 수 있다.
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
예를 들어 ubuntu를 베이스 이미지로 하고 vim을(ubuntu 이미지는 vim이 없다.) 포함하는 이미지를 만들기를 원한다면 아래와 같이 RUN으로 패키지를 설치 할 수 있다.
RUN apt-get update
RUN apt-get -y install vim

CMD

CMD는 아래와 같이 사용 할 수 있다.
  • CMD ["executable","param1","param2"] (exec 시스템 콜 형식)
  • CMD ["param1","param2"] (ENTRYPOINT에서 사용하는 기본 형식)
  • CMD command param1 param2 (shell 형식)
CMD는 Dockerfile에 하나만 설정 할 수 있다. 만약 두 개 이상의 CMD가 있다면, 마지막에 있는 하나의 CMD만 실행된다.

테스트를 위해서 간단한 Dockerfile을 만들었다.
$ cat Dockerfile
FROM ubuntu
CMD echo "This is a test." | wc -

$ docker build -t mytest .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM ubuntu
 ---> 2fa927b5cdd3
Step 2 : CMD echo "This is a test." | wc -
 ---> Running in 04ce1bde3601
 ---> d72e882ec83b
mytest 라는 이름의 도커 이미지를 만들었다. 실행해보자.
$ docker run mytest
      1       4      16 -
CMD에 설정한 명령어가 실행되는 걸 확인 할 수 있다. 도커는 shell을 실행 할 수 있다면 자동으로 /bin/sh -c를 이용해서 명령을 실행한다.

만약 shell을 실행하고 싶지 않다면 아래와 같은 형식으로 사용하면 된다.
FROM ubuntu
CMD ["/usr/bin/wc", "--help"]

RUN과 CMD를 혼동하는 경우가 있다. RUN은 실행한 결과를 이미지에 커밋(commit) 하기 위해서, 즉 새로운 컨테이너 이미지를 만들 때 사용한다. CMD는 이미지에서 컨테이너를 만들 때 실행할 명령을 설정하기 위해서 사용한다.

LABEL

LABEL <key>=<value> <key>=<value> <key>=<value> ...
라벨은 키-값 쌍으로 이루어지며, 이미지에 추가적인 정보를 설정한다. 이미지는 하나 이상의 라벨을 가질 수 있는다. 컨테이너가 만들어지면 이 정보도 읽을 수 있는데, 외부 프로그램이 읽어서 추가적인 작업을 할 때 특히 유용하게 사용 할 수 있다. Traefik 같은 로드밸런서의 경우 LABEL을 읽어서, 로드밸런서 룰을 설정한다.

EXPOSE

EXPOSE <port> [<port>...]
EXPOSE는 컨테이너가 만들어질 때, 설정된 포트(PORT)로 바인드 한다는 것을 알려준다. EXPOST를 한다고 해서 컨테이너의 포트에 접근 할 수 있다는 것은 아니다. 이를 수행하려면, -p 플래그를 이용해서 특정 포트를 공개하거나 혹은 -P 플래그를 이용해서 모든 포트를 공개해야 한다.

ADD

ADD는 두가지 방식으로 사용 할 수 있다.
  • ADD <src>... <dst>
  • ADD ["<src>",... "<dst>"]
ADD는 (로컬 혹은, url)파일을 이미지의 <dst>로 복사하기 위해서 사용한다. 하나 이상의 <src> 파일을 설정 할 수 있다. 와일드카드등을 이용해서 파일을 매칭 할 수 있다.
ADD home* /mydir/     # home으로 시작하는 모든 파일을 /mydir로 복사한다.
ADD hom?.txt /mydir/  # ?은 하나의 문자에 매칭된다. 예. home.txt, homa.txt
<dst>는 이미지상의 완전한 경로 혹은 WORKDIR을 기준으로 하는 상대 경로로 설정할 수 있다.
ADD test relativeDir/      # "test" 파일을 WORKDIR/relativeDir/ 로 복사한다.
ADD test /absoluteDir/     # "test" 파일을 /absoluteDir/ 로 복사한다.

COPY

COPY는 두 가지 방식으로 사용 할 수 있다.
  • COPY <src>... <dst>
  • COPY ["<src>",... "<dst>"]
COPY는 <src> 파일을 이미지의 <dst>로 복사한다. ADD와 매우 비슷한데, 아래의 차이점이 있다.
  1. ADD는 <src>로 URL을 사용 할 수 있다.
  2. ADD는 <src>가 인식 할 수 있는 압축 파일이라면, "풀린 다음" <dst>로 복사된다.

ENTRYPOINT

ENTRYPOINT는 두 가지 방식으로 사용 할 수 있다.
  • ENTRYPOINT ["executable", "param1", "param2"] (exec 형식)
  • ENTRYPOINT command param1 param2 (shell 형식)
ENTRYPOINT는 컨테이너가 만들어질 때 실행할 명령을 설정한다. 예를 들어서 아래와 같이 nginx 이미지를 nginx 프로그램이 실행이 된다.
docker run -it --rm -p 80:80 nginx

Docker 파일 예제

MongoDB

FROM ubuntu
MAINTAINER Kimbro Staken

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
RUN echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" | tee -a /etc/apt/sources.list.d/10gen.list
RUN apt-get update
RUN apt-get -y install apt-utils
RUN apt-get -y install mongodb-10gen

#RUN echo "" >> /etc/mongodb.conf

CMD ["/usr/bin/mongod", "--config", "/etc/mongodb.conf"] 

Mysql-Server

FROM ubuntu:14.04

MAINTAINER Kimbro Staken version: 0.1

ADD ./mysql-setup.sh /tmp/mysql-setup.sh
RUN /bin/sh /tmp/mysql-setup.sh

# Adding this will expose mysql on a random host port. It's recommended to avoid this. Other containers on the same 
# host can use the service without it.
#EXPOSE 3306

CMD ["/usr/sbin/mysqld"]
mysql-setup.sh
#!/bin/sh

# Keep upstart from complaining
RUN dpkg-divert --local --rename --add /sbin/initctl
RUN ln -s /bin/true /sbin/initctl

apt-get update && apt-get install -y mysql-server && apt-get clean && rm -rf /var/lib/apt/lists/*

sed -i -e"s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/my.cnf

/usr/sbin/mysqld &
sleep 5
echo "GRANT ALL ON *.* TO admin@'%' IDENTIFIED BY 'mysql-server' WITH GRANT OPTION; FLUSH PRIVILEGES" | mysql

한글 설정

도커의 우분투 리눅스 기본이미지는 영어다. 한글을 사용하고 싶다면, 아래와 같은 작업이 필요하다.
FROM ubuntu:14.04
		 
RUN apt-get update

RUN apt-get install  -y language-pack-ko
			 
# set locale ko_KR
RUN locale-gen ko_KR.UTF-8

ENV LANG ko_KR.UTF-8
ENV LANGUAGE ko_KR.UTF-8
ENV LC_ALL ko_KR.UTF-8

CMD /bin/bash	

참고