목차
Dockerfile
- Dockerfile 은 필요한 최소한의 패키지를 설치하고 동작하기 위한 자신만의 설정을 담은 파일
- 이 파일로 이미지를 생성(빌드) 가능
- 패키지 설치, 환경 변수 변경, 설정 파일 변경 등 다양한 작업을 하나하나 컨테이너를 만들고 설정을 적용할 필요 없이 Dockerfile 을 사용하여 적용할 수 있고, 사용자의 실수로 인한 설정 누락 예방 등 다양한 장점이 있다.
Dockerfile 이미지 만들기 명령어
docker build -t 새로운이미지이름 도커파일의경로
Dockerfile 문법
주석 (Comments)
# 주석 시작
# 이 문장은 제외됨
FROM nginx:alpine
~~
FROM
- Base Image
- 새 컨테이너 이미지는 기존의 Base 이미지에서 시작한다는 의미로 어떠한 시스템, 또는 프로그램을 실행하기 위해 처음부터 운영체제를 설치할 필요가 없다는 의미
- 3가지 문법 존재
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
FROM ubuntu:16.04
RUN
- RUN 은 Dockerfile 이 이미지를 생성하는 과정에서 실행될 명령어를 지칭
-즉 현재 이미지 맨 위의 새 계층에서 명령을 실행하고 그 결과를 저장
RUN 으로 시작하는 명령어는 각각의 새 레이어를 생성하므로 레이어 수를 최소화하기 위해 && 접속사를 사용한다.
1)첫번째 방법
RUN yum --disablerepo=* --enablerepo="centos-7-server-rpms"
RUN yum update -y
RUN yum install -y nginx
2)두번째 방법
RUN yum --disablerepo=* --enablerepo="centos-7-server-rpms" && yum update -y && yum install -y nginx
두 방법 다 결과는 똑같은데 RUN의 개수가 다르다. RUN의 개수는 Layer의 개수와 연관된다.
즉, RUN 3개면 LAYER 3개 생성 RUN 1개면 LAYER 1개 생성이 된다.
도커의 철학에 따르기 위해 레이어수를 줄이는 방식을 사용해야 한다.
CMD
- CMD 는 Dockerfile 이 이미지로 생성된 이후, 컨테이너로 만들어지며 실행되는 ‘첫 명령어’의 기본 인수를
제공하기 위해 사용
- Dockerfile 내부에 단 하나의 CMD 명령어만 존재해야 한다.
- 3가지 문법
1)일반적인 방법(JSON 스타일)
CMD ["command", "param1", "param2", ...]
2) ENTRYPOINT 명령어의 기본 파라미터로 넘겨주는 방법
ENTRYPOINT [“command”, “param1”,”param2”]
CMD ["param1", "param2", ...]
3) Shell 커맨드처럼 사용하는 방법
CMD <command> <param1> <param2> ...
CMD ["httpd", "-D", "FOREGROUND"]
단 하나의 CMD 만 동작하며 만일 여러 개의 CMD 명령어를 사용하면, 맨 마지막에 있는 CMD 만 동작한다.
ENTRYPOINT
- 컨테이너를 생성할 때 실행되는 기본 명령어를 지정
- 2 가지의 문법
1) 일반적으로 사용하는 json 스타일 방법
ENTRYPOINT ["command", "param1", "param2", ...]
2) Shell 커맨드처럼 사용하는 방법
ENTRYPOINT <command> <param1> <param2> ...
ENTRYPOINT [“httpd”]
CMD ["-D", "FOREGROUND"]
ENTRYPOINT 와 CMD 간의 관계
- ENTRYPOINT 와 CMD 모두 컨테이너가 실행될 때에 어떠한 명령어가 실행되야 할 지를 정의
1. Dockerfile 에는 최소한 둘(ENTRYPOINT, CMD) 중 하나의 명령을 가지고 있어야 한다.
2. ENTRYPOINT 는 컨테이너를 실행 가능한 형태로 만들 때(데몬 프로세스처럼) 사용된다.
3. CMD 는 ENTRYPOINT 가 실행 가능한 형태의 컨테이너로 동작할 때에 기본 인자 설정 값으로
사용되거나, 컨테이너 내에서 임시로 명령을 내릴 때에 사용된다.
4. CMD 는 컨테이너가 실행될 때에 입력 받은 인자에 의해 무시될 수 있다.
WORKDIR
- 생성할 컨테이너 내의 현재 경로를 나타낸다.
- 컨테이너가 실행되기 이전에 수행할 어떠한 작업들을 하기 이전에, base directory 같은 개념이 되는
경로를 지칭해준다.
WORKDIR /usr/share/nginx/html
COPY & ADD
COPY
- 이미지 생성 시, 호스트의 파일을 이미지 내부로 복사할 수 있는 명령어
- 대개 설정 파일 등을 복사할 때에 사용
- 원격지의 파일 복사는 지원하지 않음. ONLY 로컬에 있는 파일만 컨테이너로 복사 가능
- 호스트에 있는 파일을 복사할 때, Dockerfile 파일이 존재하는 경로보다 하부 경로에 위치하는 파일만 복사 가능
COPY <호스트에 있는 파일> <이미지 내부의 파일> :json 스타일
COPY ["<호스트에 있는 파일>","<이미지 내부의 파일>"] : shell 명령어 스타일
- 정확한 문자열 대신에 간단한 정규식도 지원하므로 여러 개의 파일을 복사하는 것도 가능
COPY sites-enabled/* /etc/nginx/sites-enabled/
ADD
- 원격지의 파일을 복사해서 컨테이너의 파일 시스템에 복사 가능
ADD http://servera.com/filename.pdf /var/www/html
USER
USER 는 컨테이너 내에서 명령들이 실행될 때에 이를 실행하기에 필요한 사용자를 설정해주는 명령
USER apache
VOLUME
- 컨테이너의 데이터를 호스트 OS 에 저장하거나, 컨테이너들간에 데이터를 공유가 가능하게 할 수 있음
- Dockerfile 에서 아래와 같이 생성한 볼륨은 호스트 OS 의 /var/lib/docker/volumes 에 생성되며, Docker에서 자동 생성한 hash 값으로 디렉토리가 생성
FROM centos:7
VOLUME ["/var/log/", "/data/"]
volume을 여러개 지정할 수 있음
EXPOSE
- 컨테이너가 런타임에 지정된 네트워크 포트에서 수신한다는 의미
EXPOSE 80
- docker run -p옵션과 유사. 차이점은, -p옵션은 컨테이너의 특정 포트를 외부에 오픈하고, 해당 포트를 호스트 PC의 특정 포트와 매핑시키는 것까지 알아서 해주지만, EXPOSE는 걍 단순히 포트를 열어주기만 한다
결국, 도커파일에 EXPOSE로 포트를 열어주었더라도, docker run을 할 때, p옵션을 쓰게 된다.
ENV & ARG
- 컨테이너에서 사용할 수 있는 환경변수를 정의
- ENV 는 Dockerfile 또는 컨테이너 안에서 환경 변수로 사용이 가능하고, ARG 는 Dockerfile 에서만 사용이
가능하다.
- ARG 의 경우 Dockerfile 작성하기 위해 필요한 변수를 선언하여 Dockerfile 을 좀 더 편하게 작성할 수 있고, ENV 는 변수 선언은 물론, 컨테이너 안에서 사용할 환경 변수(작업 디렉토리 지정) 등 선언하여 사용할 수있다.
ENV MYSQL_ROOT_PASSWORD="my_password" \
MYSQL_DATABASE "my_database"
# [key]=[value]
ARG myName=nirsa
ARG myAddress=nirsa.tistory.com
LABEL
- 이미지에 일반적인 메타데이터를 추가하기 위해 사용
- 단순히 키:값 쌍으로 구성
ONBUILD
- ONBUILD 는 빌드 완료 후 생성된 이미지가 다른 Dockerfile 에서 FROM 으로 불러질 때 실행되는 명령
Dockerfile 예시
밑의 Dockerfile은 CentOS 환경에서 mariadb를 설치한다
FROM centos:centos7
MAINTAINER The CentOS Project <cloud-ops@centos.org>
LABEL Vendor="CentOS"
LABEL License=GPLv2
LABEL Version=5.5.41
LABEL Build docker build --rm --tag centos/mariadb55 .
RUN yum -y install --setopt=tsflags=nodocs epel-release && \
yum -y install --setopt=tsflags=nodocs mariadb-server bind-utils pwgen psmisc hostname && \
yum -y erase vim-minimal && \
yum -y update && yum clean all
# MARIADB 설치 => 얘는 CENTOS에 MARIADB를 설치한 이미지
# Fix permissions to allow for running on openshift
//FIX PERMISSIONS.SH 파일하고 DOCKER-ENTRYPOINT.SH 파일 만들어야 함
COPY fix-permissions.sh ./
RUN ./fix-permissions.sh /var/lib/mysql/ && \
./fix-permissions.sh /var/log/mariadb/ && \
./fix-permissions.sh /var/run/
COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
# Place VOLUME statement below all changes to /var/lib/mysql
VOLUME /var/lib/mysql
# By default will run as random user on openshift and the mysql user (27)
# everywhere else
USER 27
EXPOSE 3306
CMD ["mysqld_safe"]