$ 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은 베이스 이미지(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는 이미지에서 컨테이너를 만들 때 실행할 명령을 설정하기 위해서 사용한다.
라벨은 키-값 쌍으로 이루어지며, 이미지에 추가적인 정보를 설정한다. 이미지는 하나 이상의 라벨을 가질 수 있는다. 컨테이너가 만들어지면 이 정보도 읽을 수 있는데, 외부 프로그램이 읽어서 추가적인 작업을 할 때 특히 유용하게 사용 할 수 있다. 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와 매우 비슷한데, 아래의 차이점이 있다.
ADD는 <src>로 URL을 사용 할 수 있다.
ADD는 <src>가 인식 할 수 있는 압축 파일이라면, "풀린 다음" <dst>로 복사된다.
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
Contents
DockerFile
DockerFile로 부터 이미지 만들기
형식
Envirionment Replacement
FROM
MAINTAINER
RUN
CMD
LABEL
EXPOSE
ADD
COPY
ENTRYPOINT
Docker 파일 예제
MongoDB
Mysql-Server
한글 설정
참고
Recent Posts
Archive Posts
Tags