Dockerfile이란?

docker 이미지를 만들게 해주는 파일.
내가만든 프로젝트를 dockerfile로 만들고, 이걸 활용하면 docker 이미지로 쓸 수 있게 한다.

1. Dockerfile안에 베이스 이미지 넣기

# Dockerfile
FROM [이미지명]
FROM [이미지명]:[태그명]

태그명을 적지 않으면 가장 최신 버전을 사용한다.

2. Dockerfile 기반 이미지 만들기

# 터미널
docker build -t my-server .
docker build -t my-server:beta .

docker build // 도커에게 빌드를 명령
-t 태그 // 안적으면 latest, 적으면 적은 태그가 적힌다.
. // 상대 경로로, 점 하나는 "현재 여기"를 표시

3. 이미지 기반 컨테이너 띄우기

docker run -d my-server

my-server 실행해보기

4. 컨테이너 조회

docker ps -a

my-server의 STATUS가 Exited 로 적혀있다..!
이유 : FROM 이미지명 만 적으면 저거 실행하고 끝내버림.
내부 확인하려면?
일단 실행중이지 않기 때문에, exec로 내부를 볼 수 없음.
그럼 어떻게 하는가?

5. 꼼수

# Dockerfile
FROM 이미지명
ENTRYPOINT ["/bin/bash", "-c", "sleep 500"]

이렇게 하고 다시 빌드부터 해보면,
docker ps -a에서도,
docker exec -it 컨테이너명 bash에서도
실행이 되고있는걸 확인할 수 있다.
저 명령어는, 이후 디버깅할 때 유용하게 쓸 수 있다. 마치 셀레니움 할때 time.sleep(5)와 같은 느낌


COPY

FROM ubuntu
COPY a.txt /a.txt
COPY ./ / # 모든 파일을 다 붙여넣겠다
COPY *.txt /text-files/ #와일드카드같은것도 사용 가능
ENTRYPOINT ["/bin/bash", "-c", "sleep 500"]

해당 이미지에 호스트 a.txt 파일을 컨테이너 a.txt를 집어넣겠다.
폴더를 복사할땐 COPY folder /folder/ <<- 슬래시로 가둬야 정상적으로 폴더로 인식됨


.dockerignore

a.txt # a.txt는 넣지마라

gitignore처럼 , 추적을 원치 않는 파일을 지정할 수 있음. COPY에서 제외됨.


ENTRYPOINT

컨테이너가 시작될 때 실행되는 명령어.
즉, 컨테이너(미니컴퓨터)가 실행되고 바로 실행되는 명령어.

From ubuntu
ENTRYPOINT ["/bin/bash", "-c", "echo hello"]

해보면 echo hello 하고 바로 꺼지는 도커파일 생성이 된다.


RUN

run은 이미지 생성 과정에서 명령어를 실행시켜야 할 때 사용.
RUN vs ENTRYPOINT
RUN = 이미지 생성 과정에서 필요한 명령어를 실행시킬 때.
ENTRYPOINT = 이미지 생성 이후 컨테이너 실행된 직후에.
RUN 예제

FROM ubuntu
RUN apt update && apt install -y git

즉, 이미지 생성 중에 git이 설치된다.
RUN = docker build 중에
ENTRYPOINT = docker run 할 때


WORKDIR

작업 디렉토리를 전환. 마치 윈도우에서 cd (change directory) 느낌
이후 도커파일에 오는 모든 명령어들은 해당 위치에서 실행됨

FROM ubuntu
WORKDIR /new_directory
COPY ./ ./

위와같이, new_directory 라는 디렉토리로 이동 후 모든 파일을 복사하겠다는 뜻.
기본적으로는 루트 디렉토리에 파일이 저장되는데, 옮긴 후 COPY할 수 있다.


EXPOSE

컨테이너가 사용하는 포트를 명시적으로 알려주는 용도.
근데, 진짜 포트를 열지 않음.
docker run -p 옵션에서 진짜 포트를 염
그냥 주석처럼 "가이드라인"을 제공하는 느낌.

FROM ubuntu
EXPOSE 3000

주석처럼 없어도 되나, 적어두면 개발자나 도구에게 감초 역할을 한다.


전체 흐름

FROM node    # 기본적으로 node를 실행한다
WORKDIR /app    # 디렉토리를 app 폴더로 이동
copy . .    # 호스트의 현재 디렉토리 내 모든 파일을 복사, app 폴더에 붙여넣어짐
RUN npm install    # 이미지 생성 중 npm install을 실행
RUN npm run build    # 이미지 생성 중 npm run build를 실행
EXPOSE 3000    # 3000번 포트를 쓸거라고 알려만 준다.
ENTRYPOINT ["node", "dist/main.js"]    # node dist/main.js를 컨테이너에서 실행하라

효율적인 도커 파일 생성 방법

  1. alpine 빌드를 사용.
    alpine = 불필요한 프로그램을 포함하지 않고 이미지 크기를 최소화한 버전.

변경이 적은 명령어를 위쪽에 배치하기.
dockerfile은 빌드할 때 docker cache를 만든다. 명령어 실행 내역을 캐시에 저장했다가, 다음에 다시 dockerfile을 재사용할 때 캐시를 이용하여 빠르게 빌드되게 만든다.
근데 만약 dockerfile 중간에 변경이 생긴다면, 그 아래에 있는 모든 명령어는 변경이 없음에도 다시 빌드된다.



이미지에서 main.c가 바뀐다면,
1,2 번 라인은 캐시에 저장되어있어 빨리 실행되나 3,4,5번은 캐시에 없던 내용이라 "무효화"된다.
모르겠으면, 그냥

"변경이 적은 명령어를 위쪽에 배치하기"

 

+ Recent posts