Dockerfile과 Bash 
이재홍 
http://pyrasis.com 
Docker Seoul Meetup #2 / September 27, 2014
Dockerfile 
이미지를 생성하기 위한 설정 파일 
RUN, CMD, ENTRYPOINT에서 Shell로 명령 실행 
RUN: 이미지를 생성할 때 
CMD, ENTRYPOINT: 컨테이너를 시작할 때, 주로 스크 
립트를 실행
RUN은 독립적이다 
RUN cd /etc 
RUN echo "127.0.0.1 hello" >> hosts 
# 동작 안함 
올바른 사용 방법 
RUN cd /etc && echo "127.0.0.1 hello" >> hosts 
WORKDIR /etc 
RUN echo "127.0.0.1 hello" >> hosts
RUN에서 사용자 입력 창, 프롬프트가 나오면 안된다 
데비안(우분투)에서는 ENV로 환경 변수 설정 
ENV로 설정한 환경 변수는 다음에 나오는 RUN에 모두 적용됨 
Bash와 리다이렉션 파이프, 기타 방법을 사용하여 자동화 
FROM ubuntu:14.04 
ENV DEBIAN_FRONTEND noninteractive 
RUN apt-get update 
RUN echo "mysql-server mysql-server/root_password password" | debconf-set-selections 
RUN echo "mysql-server mysql-server/root_password_again password" | debconf-set-selections 
RUN apt-get install -y mysql-server
Bash(Bourne Again Shell) 
대부분 배포판에서 기본 Shell 
CentOS: sh -> bash 
Ubuntu: sh -> dash(Debian Almquist Shell) 
각종 유닉스 명령과 조합하여 사용
표준 출력(stdout) 리다이렉션 
$ echo "hello" > ./hello.txt 
$ echo "hello" > /dev/null 
표준 입력(stdin) 리다이렉션 
$ echo "cat" < ./hello.txt 
표준 출력 내용을 파일에 추가 
$ echo "world" >> ./hello.txt 
표준 에러(stderr)를 파일로 저장, 추가 
2> 
2>>
표준 출력(stdout)과 표준 에러(stderr)를 모두 파일로 저장 
&> 
표준 출력(stdout)을 표준 에러(stderr)로 보냄 
1>&2 
표준 에러(stderr)를 표준 출력(stdout)으로 보냄 
2>&1 
$ cat world.txt > /dev/null 2>&1 
표준 출력을 다른 명령의 표준 입력으로 보냄 
$ ls -al | grep .txt
변수 설정 
스크립트 내에서만 유효 
$ HELLO=world 
환경 변수 설정 
현재 로그인한 사용자 계정 내에서 유효 
$ export HELLO=world
명령 실행 결과(stdout)를 변수화 
$ sudo docker rm $(docker ps -aq) 
$ echo $(date) 
$ sudo docker rm `docker ps -aq` 
$ echo `date` 
변수를 처리하는 않는 문자열 
$ echo "$USER" 
pyrasis 
변수를 처리하지 않는 문자열 
$ echo '$USER' 
$USER
문자열 안에서 변수처리 
$ str="World" 
$ echo "Hello ${str}" 
Hello World 
$ echo "Hello $str" 
Hello World 
값이 있으면 그대로 사용, NULL이면 기본값 사용 
$ WORLD= 
$ WORLD=${WORLD:-"abcd"} 
$ echo $WORLD 
abcd
한 줄을 여러 줄로 표현 
$ sudo docker run -d --name hello busybox:latest 
$ sudo docker run  
-d  
--name hello  
busybox:latest
문자열을 명령의 표준 입력으로 보냄 
$ cat <<< "User name is $USER" 
User name is pyrasis 
여러 줄의 문자열을 명령의 표준 입력으로 보냄 
$ cat > ./hello.txt <<EOF 
Hello World 
Host name is $(hostname) 
User name is $(USER) 
EOF
지정한 형식대로 출력. 파이프와 연동하여 명령에 입력하는 효과 
$ printf 80nexampleuserny | example-config 
Port: 80 
User: exampleuser 
Save Configuration (y/n): y 
텍스트 파일에서 문자열 변경 
$ sed -i "s/hello/world/g" hello.txt 
Git 리비전 구하기. 실행 결과를 변수화 
#!/bin/bash 
REVISION=$(expr substr $(git rev-parse --verify HEAD) 1 7)
Dockerfile 예제
리다이렉션을 활용하여 파일에 내용 추가 
FROM ubuntu:14.04 
RUN apt-get update 
RUN apt-get install -y nginx 
RUN echo "ndaemon off;" >> /etc/nginx/nginx.conf 
RUN chown -R www-data:www-data /var/lib/nginx 
WORKDIR /etc/nginx 
CMD ["nginx"] 
EXPOSE 80 
EXPOSE 443
리다이렉션 활용 
여러 줄의 문자열을 파일로 저장 
변수 처리 
#!/bin/bash 
mysql_install_db --user mysql > /dev/null 
cat > /tmp/sql <<EOF 
USE mysql; 
FLUSH PRIVILEGES; 
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; 
UPDATE user SET password=PASSWORD("$MYSQL_ROOT_PASSWORD") WHERE user='root'; 
EOF 
mysqld --bootstrap --verbose=0 < /tmp/sql 
rm -rf /tmp/sql 
mysqld 
ADD entrypoint.sh /entrypoint.sh 
RUN chmod +x /entrypoint.sh 
ENTRYPOINT /entrypoint.sh
rbenv로 Ruby 설치 
FROM ubuntu:14.04 
RUN apt-get update 
RUN apt-get install -y autoconf bison build-essential libssl-dev  
libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev git 
RUN apt-get install -y nginx nodejs curl libpq-dev 
RUN git clone https://github.com/sstephenson/rbenv.git /root/.rbenv 
RUN git clone https://github.com/sstephenson/ruby-build.git /root/.rbenv/plugins/ruby-build 
ENV PATH /root/.rbenv/bin:/root/.rbenv/shims:$PATH 
ENV CONFIGURE_OPTS --disable-install-doc 
RUN rbenv install 2.1.3 
RUN rbenv global 2.1.3 
RUN rbenv init - 
RUN echo 'gem: --no-rdoc --no-ri' >> /root/.gemrc 
RUN gem install bundler 
RUN rbenv rehash 
RUN echo "daemon off;" >> /etc/nginx/nginx.conf 
RUN rm -rf /etc/nginx/sites-enabled/default 
ADD exampleapp.conf /etc/nginx/sites-enabled/exampleapp.conf 
WORKDIR /tmp 
ADD Gemfile Gemfile 
ADD Gemfile.lock Gemfile.lock 
RUN bundle install 
ADD ./ /var/www/exampleapp 
WORKDIR /var/www/exampleapp 
RUN chmod +x entrypoint.sh 
EXPOSE 80 
ENTRYPOINT ./entrypoint.sh
리다이렉션 활용 
printf를 활용하여 자동으로 설정 값 적용 
파이프 활용 
변수 처리 
#!/bin/bash 
echo "export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe" > /etc/profile.d/oracle.sh 
echo "export ORACLE_SID=XE" >> /etc/profile.d/oracle.sh 
echo "export PATH=$PATH:/u01/app/oracle/product/11.2.0/xe/bin" >> /etc/profile.d/oracle.sh 
source /etc/profile.d/oracle.sh 
printf 8080n1521n$ORACLE_PASSWORDn$ORACLE_PASSWORDnn | /etc/init.d/oracle-xe configure 
echo "root:$ORACLE_PASSWORD" | chpasswd 
/usr/sbin/sshd -D
sed로 설정 파일 수정 
FROM ubuntu:14.04 
RUN cd /etc/apt &&  
sed -i 's/archive.ubuntu.com/ftp.daum.net/g' sources.list &&  
sed -i 's/archive.ubuntu.com/ftp.daum.net/g' sources.list.d/proposed.list 
RUN apt-get update 
RUN apt-get install -y nginx
변수 처리 
한 줄을 여러 줄로 표현 
[Unit] 
Description=Announce Web 
BindsTo=web.service 
[Service] 
EnvironmentFile=/etc/environment 
ExecStart=/bin/sh -c  
"while true;  
do  
etcdctl set /services/web/nginx  
'{ "host": "${COREOS_PUBLIC_IPV4}", "port": 80 }'  
--ttl 60;  
sleep 45;  
done" 
ExecStop=/usr/bin/etcdctl rm /services/web/nginx 
[X-Fleet] 
MachineOf=web.service
"가장 빨리 만나는 Docker" 출간 및 원고 공개 
http://www.pyrasis.com/private/2014/11/30/publish-docker-for-the-really-impatient-book
"아마존 웹 서비스를 다루는 기술" 출간 및 원고 공개 
http://www.pyrasis.com/private/2014/09/30/publish-the-art-of-amazon-web-services-book

Dockerfile과 Bash

  • 1.
    Dockerfile과 Bash 이재홍 http://pyrasis.com Docker Seoul Meetup #2 / September 27, 2014
  • 2.
    Dockerfile 이미지를 생성하기위한 설정 파일 RUN, CMD, ENTRYPOINT에서 Shell로 명령 실행 RUN: 이미지를 생성할 때 CMD, ENTRYPOINT: 컨테이너를 시작할 때, 주로 스크 립트를 실행
  • 3.
    RUN은 독립적이다 RUNcd /etc RUN echo "127.0.0.1 hello" >> hosts # 동작 안함 올바른 사용 방법 RUN cd /etc && echo "127.0.0.1 hello" >> hosts WORKDIR /etc RUN echo "127.0.0.1 hello" >> hosts
  • 4.
    RUN에서 사용자 입력창, 프롬프트가 나오면 안된다 데비안(우분투)에서는 ENV로 환경 변수 설정 ENV로 설정한 환경 변수는 다음에 나오는 RUN에 모두 적용됨 Bash와 리다이렉션 파이프, 기타 방법을 사용하여 자동화 FROM ubuntu:14.04 ENV DEBIAN_FRONTEND noninteractive RUN apt-get update RUN echo "mysql-server mysql-server/root_password password" | debconf-set-selections RUN echo "mysql-server mysql-server/root_password_again password" | debconf-set-selections RUN apt-get install -y mysql-server
  • 5.
    Bash(Bourne Again Shell) 대부분 배포판에서 기본 Shell CentOS: sh -> bash Ubuntu: sh -> dash(Debian Almquist Shell) 각종 유닉스 명령과 조합하여 사용
  • 6.
    표준 출력(stdout) 리다이렉션 $ echo "hello" > ./hello.txt $ echo "hello" > /dev/null 표준 입력(stdin) 리다이렉션 $ echo "cat" < ./hello.txt 표준 출력 내용을 파일에 추가 $ echo "world" >> ./hello.txt 표준 에러(stderr)를 파일로 저장, 추가 2> 2>>
  • 7.
    표준 출력(stdout)과 표준에러(stderr)를 모두 파일로 저장 &> 표준 출력(stdout)을 표준 에러(stderr)로 보냄 1>&2 표준 에러(stderr)를 표준 출력(stdout)으로 보냄 2>&1 $ cat world.txt > /dev/null 2>&1 표준 출력을 다른 명령의 표준 입력으로 보냄 $ ls -al | grep .txt
  • 8.
    변수 설정 스크립트내에서만 유효 $ HELLO=world 환경 변수 설정 현재 로그인한 사용자 계정 내에서 유효 $ export HELLO=world
  • 9.
    명령 실행 결과(stdout)를변수화 $ sudo docker rm $(docker ps -aq) $ echo $(date) $ sudo docker rm `docker ps -aq` $ echo `date` 변수를 처리하는 않는 문자열 $ echo "$USER" pyrasis 변수를 처리하지 않는 문자열 $ echo '$USER' $USER
  • 10.
    문자열 안에서 변수처리 $ str="World" $ echo "Hello ${str}" Hello World $ echo "Hello $str" Hello World 값이 있으면 그대로 사용, NULL이면 기본값 사용 $ WORLD= $ WORLD=${WORLD:-"abcd"} $ echo $WORLD abcd
  • 11.
    한 줄을 여러줄로 표현 $ sudo docker run -d --name hello busybox:latest $ sudo docker run -d --name hello busybox:latest
  • 12.
    문자열을 명령의 표준입력으로 보냄 $ cat <<< "User name is $USER" User name is pyrasis 여러 줄의 문자열을 명령의 표준 입력으로 보냄 $ cat > ./hello.txt <<EOF Hello World Host name is $(hostname) User name is $(USER) EOF
  • 13.
    지정한 형식대로 출력.파이프와 연동하여 명령에 입력하는 효과 $ printf 80nexampleuserny | example-config Port: 80 User: exampleuser Save Configuration (y/n): y 텍스트 파일에서 문자열 변경 $ sed -i "s/hello/world/g" hello.txt Git 리비전 구하기. 실행 결과를 변수화 #!/bin/bash REVISION=$(expr substr $(git rev-parse --verify HEAD) 1 7)
  • 14.
  • 15.
    리다이렉션을 활용하여 파일에내용 추가 FROM ubuntu:14.04 RUN apt-get update RUN apt-get install -y nginx RUN echo "ndaemon off;" >> /etc/nginx/nginx.conf RUN chown -R www-data:www-data /var/lib/nginx WORKDIR /etc/nginx CMD ["nginx"] EXPOSE 80 EXPOSE 443
  • 16.
    리다이렉션 활용 여러줄의 문자열을 파일로 저장 변수 처리 #!/bin/bash mysql_install_db --user mysql > /dev/null cat > /tmp/sql <<EOF USE mysql; FLUSH PRIVILEGES; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; UPDATE user SET password=PASSWORD("$MYSQL_ROOT_PASSWORD") WHERE user='root'; EOF mysqld --bootstrap --verbose=0 < /tmp/sql rm -rf /tmp/sql mysqld ADD entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT /entrypoint.sh
  • 17.
    rbenv로 Ruby 설치 FROM ubuntu:14.04 RUN apt-get update RUN apt-get install -y autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev git RUN apt-get install -y nginx nodejs curl libpq-dev RUN git clone https://github.com/sstephenson/rbenv.git /root/.rbenv RUN git clone https://github.com/sstephenson/ruby-build.git /root/.rbenv/plugins/ruby-build ENV PATH /root/.rbenv/bin:/root/.rbenv/shims:$PATH ENV CONFIGURE_OPTS --disable-install-doc RUN rbenv install 2.1.3 RUN rbenv global 2.1.3 RUN rbenv init - RUN echo 'gem: --no-rdoc --no-ri' >> /root/.gemrc RUN gem install bundler RUN rbenv rehash RUN echo "daemon off;" >> /etc/nginx/nginx.conf RUN rm -rf /etc/nginx/sites-enabled/default ADD exampleapp.conf /etc/nginx/sites-enabled/exampleapp.conf WORKDIR /tmp ADD Gemfile Gemfile ADD Gemfile.lock Gemfile.lock RUN bundle install ADD ./ /var/www/exampleapp WORKDIR /var/www/exampleapp RUN chmod +x entrypoint.sh EXPOSE 80 ENTRYPOINT ./entrypoint.sh
  • 18.
    리다이렉션 활용 printf를활용하여 자동으로 설정 값 적용 파이프 활용 변수 처리 #!/bin/bash echo "export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe" > /etc/profile.d/oracle.sh echo "export ORACLE_SID=XE" >> /etc/profile.d/oracle.sh echo "export PATH=$PATH:/u01/app/oracle/product/11.2.0/xe/bin" >> /etc/profile.d/oracle.sh source /etc/profile.d/oracle.sh printf 8080n1521n$ORACLE_PASSWORDn$ORACLE_PASSWORDnn | /etc/init.d/oracle-xe configure echo "root:$ORACLE_PASSWORD" | chpasswd /usr/sbin/sshd -D
  • 19.
    sed로 설정 파일수정 FROM ubuntu:14.04 RUN cd /etc/apt && sed -i 's/archive.ubuntu.com/ftp.daum.net/g' sources.list && sed -i 's/archive.ubuntu.com/ftp.daum.net/g' sources.list.d/proposed.list RUN apt-get update RUN apt-get install -y nginx
  • 20.
    변수 처리 한줄을 여러 줄로 표현 [Unit] Description=Announce Web BindsTo=web.service [Service] EnvironmentFile=/etc/environment ExecStart=/bin/sh -c "while true; do etcdctl set /services/web/nginx '{ "host": "${COREOS_PUBLIC_IPV4}", "port": 80 }' --ttl 60; sleep 45; done" ExecStop=/usr/bin/etcdctl rm /services/web/nginx [X-Fleet] MachineOf=web.service
  • 21.
    "가장 빨리 만나는Docker" 출간 및 원고 공개 http://www.pyrasis.com/private/2014/11/30/publish-docker-for-the-really-impatient-book
  • 22.
    "아마존 웹 서비스를다루는 기술" 출간 및 원고 공개 http://www.pyrasis.com/private/2014/09/30/publish-the-art-of-amazon-web-services-book