Dockerfile 자세히 알아보기

이승준·2024년 8월 10일
  • Dockerfile 의 명령어는 항상 FROM 으로 시작
    => 지키지 않으면 이미지가 생성되지 않는다.
  • 각 명령은 독립적으로 실행
    => cd 로 디렉토리를 이동해도 이후 명령어에는 영향이 없다.

.dockerignore

  • dockerfile 과 같은 dir 에 있는 파일을 context 라고 한다.
  • 이미지 생성 시 docker daemon 에 모든 context 가 전송된다
    => 필요 없는 context 가 전송되지 않도록 .dockerignore 를 이용해 관리
# .dockerignore
example/hello.txt
example/*.cpp # * 를 자주 이용한다
wo*
*.cpp
# .git, .svn 과 같은 디렉토리는 제외한다
.git
.svn

FROM

  • 이미지 생성 시 사용할 base image 설정
  • dockerfile 을 이용해 이미지를 생성할 때는 기존의 이미지를 이용하기 때문에 반드시 필요
FROM ubuntu # 이미지 이름만 설정하면 latest 사용
FROM ubuntu:22.04 # tag 설정 가능

여러 개 사용하기

  • FROM 을 여러 개 설정할 수 있고, 설정한 수 만큼 이미지 생성
  • C 언어 소스 파일을 컴파일하고, 실행 파일만 이미지에 넣어보자
  1. 파일 저장을 위한 dir 생성
$ mkdir hello
$ cd hello
  1. C 소스 파일 작성
// hello.c
#include <stdio.h>

int main(){
	print("Hello Docker\n");
    return 0;
}
  1. Dockerfile 에 내용 저장
FROM ubuntu:22.04 AS builder # base image 및 alias 정의

RUN apt update
RUN apt install -y gcc
WORKDIR /tmp # working directory 설정
ADD hello.c ./ # 소스파일 추가
RUN gcc hello.c -static -o hello # 소스파일 컴파일

FROM alpine:3.16.2 #
WORKDIR /tmp
# --from 옵션을 이용해 로컬이 아닌 이미지에서 파일 복사
# builder 에 있는 /tmp/hello 를 ./ 로 복사
COPY --from=builder /tmp/hello ./

CMD ["/tmp/hello"]
  • 이처럼 이미지를 두 개 생성하는 이유는, 실행 파일만을 가지고 와 이미지의 용량을 줄이기 위함이다

MAINTAINER

  • 이미지를 설정한 사람의 정보 명시
  • 보통 이름과 이메일을 기입한다.
  • 생략 가능하다
MAINTAINER Lee, Seungjun <jjdg148@gmail.com>

RUN

  • FROM 에서 설정한 이미지 위에서 스크립트나 명령을 실행
  • 실행 내역은 이미지의 history 에 기록
  • RUN 으로 실행된 빌드는 caching 된다. build 시 --no-cache 옵션을 주면 caching 되지 않는다
  • 두 가지 형식이 있다.

shell 이용

  • /bin/sh 실행 파일 이용하는 형식
  • /bin/sh 가 없으면 실행할 수 없다
# RUN <cmd> 형식
RUN echo "Hello Docker" > /tmp/hello
RUN apt install -y nginx

shell 없이 실행

  • shell script 문법이 인식되지 않아 문자를 그대로 실행 파일에 넘겨줄 수 있음
# RUN ["<실행파일>", "<매개변수>"]형식
RUN ["apt", "install", "-y", "nginx"]
RUN ["/user/local/bin/hello", "--help"]

CMD

  • 컨테이너 시작 시 실행 할 기본 명령어
  • 컨테이너 시작 : run, start 호출 시
# /bin/sh/ 로 명령 실행
CMD touch /home/hello/hello.txt

# shell 없이 실행
CMD ["mysqld", "--datadir=/var/lib/mysql", "--user=mysql"]

docker run 과의 조합

  • Dockerfile의 CMD는 기본 명령어이기 때문에 docker run 명령어에 의해 덮어씌워짐
#Dockerfile
FROM ubuntu:22.04

CMD ["echo", "hello"]

---EOF---

$ docker build --tag myImage:1.0 .
$ docker run -it --name mycontainer myImage:1.0 echo world
>> world

ENTRYPOINT

  • ENTRYPOINT 가 선언되어 있으면 명령어는 ENTRYPOINT 에, 인자는 CMD 에 선언됨
  • CMD 는 ENDPOINT 에 매개변수를 전달하는 역할을 맡고 독자적으로 실행이 불가능하다

docker run 과의 조합

  • docker run 의 인자는 ENDPOINT 의 인자로 추가된다
  • --entrypoint 옵션을 사용하면 Dockerfile에 정의된 ENTRYPOINT가 무시되고, 새로운 ENTRYPOINT가 적용
#Dockerfile
FROM ubuntu:22.04

ENTRYPOINT ["echo", "hello"]

---EOF---

$ docker build --tag myImage:1.0 .
$ docker run -it --name mycontainer myImage:1.0 echo world
>> hello echo world

$ docker run -it --name mycontainer --entrypoint="echo" myImage:1.0 world
>> world

EXPOSE

  • 호스트와 연결할 포트번호 설정
  • docker run 의 --expose 옵션과 동일
  • 포트 두 개 이상 설정 가능
EXPOSE 80 443

ENV

  • 환경 변수 설정
  • 변수 값 사용 시 $ 추가
# 환경변수 설정 후 값 출력
ENV HELLO 1234
CMD echo $HELLO

ADD

  • 이미지에 파일 추가
# ADD <복사할 파일 경로> <이미지에서 파일이 위치할 경로>
ADD hello-entrypoint.sh /entrypoint.sh
  • 복사할 파일 경로는 context 의 아래를 기준으로 한다
    => 절대경로, context 외부 경로 사용 불가
  • 이미지 추가시 압축 해제됨

COPY

  • ADD 와 달리 압축을 해제하지 않고 파일 url 사용 불가

USER

  • 명령을 실행할 사용자 계정 설정

DOCKERFILE 만들기

예제 - Ubuntu

FROM ubuntu:22.04
MAINTAINER Lee,Seungjun <jjdg148@gmail.com>
ENV TZ Asia/Seoul
WORKDIR /usr/LeeSeungjun
USER lsjdg
CMD echo lsjdg
profile
인하대학교 컴퓨터공학과

0개의 댓글