Devlog

Dockerfile 만들기 본문

데브옵스

Dockerfile 만들기

ehdrb92 2023. 1. 8. 21:14

Dockerfile은 도커 이미지를 만들기 위한 설계도이고, 이미지는 최종적으로 컨테이너를 찍어내기 위한 일종의 틀? 금형? 과 같다고 할 수 있다. 간단한 Dockerfile을 만들어 보자.

# 도커 파일 내부변수 설정
ARG DB_PORT=3306

# 파이썬 환경을 도커 허브에서 불러오기
FROM python:3.9

# 기본 작업 경로 설정
WORKDIR /app

# 필요 라이브러리 목록 복사
COPY requirements.txt ./requirements.txt

# 필요 라이브러리 설치
RUN pip install -r requirements.txt

# 서버 프로젝트 파일을 작업 경로에 복사
COPY . /app

# 환경 변수 설정
ENV DB_HOST 172.17.0.1
ENV DB_PORT $DB_PORT

# 8000번 포트 개방
EXPOSE 8000

# 개발 서버 구동
CMD ["uvicorn", "main:app", "--reload"]

위는 내가 최근에 만들게 된 FastAPI 프로젝트 서버를 도커 이미지 파일로 만드는 Dockerfile이다. 위의 각 명령어가 무엇을 뜻하는지 하나하나 뜯어보도록 하자.

FROM

FROM은 Dockerfile에서 새로운 빌드 단계를 초기화하고 후속 명령을 수행하기 위한 기본 이미지를 설정한다.

 

FROM에는 사용 가능한 모든 이미지 파일의 이름이 오게 된다. 이는 도커 허브에 있는 이미지 또한 가능하다. 자신의 로컬 호스트에 FROM에 해당하는 이미지가 존재하지 않는 경우 도커 허브에서 자동으로 내려받는다.

 

위에서는 python으로 된 프로젝트 서버를 구동하기 위해 python 이미지를 기본 이미지로 설정한 예시이다.

WORKDIR

WORKDIR은 도커 컨테이너 내부에서 후속 명령들을 수행하는 기본 경로를 설정하도록 한다. WORKDIR의 경우 필수적인 명령어는 아니다. 이를 설정하지 않을 경우 기본 경로값으로 root가 설정된다.

COPY

COPY는 Dockerfile이 존재하고 있는 경로에서 선택한 파일 또는 경로를 복사하여 도커 컨테이너에 붙여 넣기 한다.

 

여기서 한 가지 짚고 넘어가야 할 점은 위 예시에서 requirements.txt파일을 도커 내에 "./"경로로 붙여 넣기 하였는데, 만약 이전에 WORKDIR 명령어를 실행시켜 기본 경로를 변경하지 않았다면 root 경로에 복사되었을 것이다. 그런데 기본 경로를 "/app"으로 변경하였기에 후속 명령어에서 "./"이 의미하는 경로는 실제로 "./app"이 된다.

RUN

RUN은 이미지 레이어를 빌드하는 단계에서 사용되는 명령어를 정해주는 명령어이다. 보통 서버를 구동하는데 필요하는데 필요한 패키지들을 설치하거나, 설정등을 수행하는 명령어를 수행한다. 위 예시에서는 하나의 RUN 명령만 수행하였지만, 여러 줄의 명령을 수행하는 것도 가능하다. 레이어 빌드 단계에서는 다양한 명령어가 필요할 수 있기 때문이다.

EXPOSE

EXPOSE는 외부의 요청을 받아들이기 위해 열어둘 도커 컨테이너의 포트를 설정한다. EXPOSE는 필수적인 명령어는 아니다. 왜냐하면 도커 이미지를 통해 컨테이너를 띄울 때 다시 한번 포트 설정을 해야 하기 때문이다.

 

여기서 간단하게 도커 컨테이너의 포트에 대해 설명하자면 각각의 도커 컨테이너는 마치 개별의 컴퓨터와 같이 활동한다. 그렇기에 컨테이너에도 자신만의 포트들을 가지게 된다. 그런데 컨테이너는 가상의 플랫폼일 뿐 실제 포트를 가지고 있는 것이 아니다. 그렇기에 실제 로컬 호스트의 포트를 컨테이너의 포트와 연결 지어 주어야 한다.

 

만약 컨테이너를 띄울 때 컨테이너의 80번 포트에 로컬 호스트의 3000번 포트를 연결 지어 주었다고 하자. 실제 특정 요청이 로컬 호스트의 3000번 포트로 들어왔을 때 도커 컨테이너는 해당 요청을 가로채 자신의 80번 포트로 오도록 한다. 이렇게 컨테이너는 요청을 받을 수 있는 것이다.

 

그래서 해당 명령어를 수행하면 도커 컨테이너에서 열어주는 포트를 설정한 것일 뿐 로컬 호스트의 어떤 포트의 요청을 가져올 것인지를 정해준 것이 아니기에 컨테이너를 띄우는 명령어를 수행할 때 한번 더 입력해주어야 한다. 그런데 확인해본 결과 CLI의 명령어를 이용한 것이 아니라 도커 데스크톱을 이용해 컨테이너를 띄울 경우 명령어를 수행한 이미지는 컨테이너 노출 포트는 미리 설정되어 있어 로컬 호스트 포트만 설정해주면 되었다.

ENV

ENV는 컨테이너 내부 시스템에서 활용할 수 있는 환경변수를 설정하는 명령어이다. 설정해준 환경변수는 컨테이너 내의 모든 곳에서 활용할 수 있다.

 

예를 들어 위 예시와 같은 파이썬 프로젝트 컨테이너에서 활용한다고 하면, 시스템 환경변수를 불러오는 파이썬의 os.environ("DB_HOST") 명령어를 사용하면 해당 키의 값에 해당하는 172.17.0.1이 불러와지게 된다.

CMD

CMD는 이미지를 통한 컨테이너 레이어 빌드를 모두 마친 후 수행할 기본 명령어를 설정하는 것이다. 위 예시에서는 개발 서버를 구동하는 명령어를 정해주었지만 다른 기타 명령어도 가능하다. 주의할 점은 CMD를 통해 수행하는 기본 명령어는 하나의 명령만 가능하다는 점을 알아두자. 어러 줄의 명령을 명시할 경우 마지막에 명시된 명령어만 수행한다.

ARG

ARG는 해당 dockerfile내부에서 사용될 변숫값을 설정하는 데 사용된다. ENV DB_PORT는 ARG의 DB_PORT값을 불러와 설정된 모습이다. 해당 명령어는 Dockerfile내부의 어느 위치에 와도 상관없다. 다만 사용하려는 명령어 이전에만 선언한다면 상관없다.

'데브옵스' 카테고리의 다른 글

kubernetes 입문하기  (0) 2023.02.23
Docker-Compose 사용하기  (0) 2023.01.13
컨테이너 내부 서버가 통신 하는 방법  (1) 2023.01.09
도커 볼륨으로 데이터 관리하기  (0) 2023.01.08