본문 바로가기
Linux

Docker - Dockerfile 작성하기 기본 with Python

by 올엠 2024. 2. 28.
반응형

 Docker를 통한 배포의 유연성은 사용해 본 사람이라면 계속 사용할 수 밖에 없게 만든다.

특히 개발하던 코드를 서버에 배포하고자 할 때 과거 발생하는 서버의 환경 설정 문제와 서버 구성의 간편함을 제공함으로써 보다 안전하고 빠르게 배포를 완료할 수 있다.

가장 처음 Docker를 사용하고자 한다면 Dockerfile을 작성하여야 한다.

여기에서는 Dockerfile을 작성할 때 어떻게 구성할 수 있는지 기본적으로 사용되는 커멘드들에 대해서 알아보도록 하겠다.

Dockerfile 작성

Dockerfile을 작성할 때에 다음과 같은 루트로 작성을 진행하는 것을 추천한다.

  1. 필요 라이브러리 설치
  2. 도커 실행에 필요한 파일 복사
  3. 서버 환경 설정
  4. 스크립트 실행

크게 위 4가지를 순서적으로 진행하면 대부분의 도커를 생성할 수 있다.

그럼 한가지씩 들여다보도록 하자.

 

1. 기본 베이스 이미지 지정

FROM python:3.9

가장 기본적인 부분으로 FROM을 통해서 기존의 베이스가 되는 이미지를 선택하는 것이 Docker 파일의 시작이라고 할 수 있다. 이러한 이미지는 공식 Docker Hub에서 받아오는 것이 가능하다. 만약 써야하는 이미지를 확인하고자 한다면, https://hub.docker.com 에서 확인해 보면 좋다. 

사용 가능한 태그를 확인 할 수 있다.

그후 최근 기본적으로 서버 환경상 패치가 필요한 상황을 방지하기 위해서 apt-get update를 통해 서버 환경 라이브러리들을 업데이트를 진행해 준다. 

 

2. 도커 실행에 필요한 파일 복사

MKDIR /opt/server
MKDIR /opt/server/conf


COPY *.py /opt/server
COPY prod.cfg /opt/server/conf

하위 디렉토리는 MKDIR을 통해 사전에 만들어 사용하는 것이 좋다.

특히 필자의 경우 도커 파일을 제작시 환경 설정 파일을 개발 환경과 다르게 하기 때문에 환경 설정 디렉토리와 환경설정 파일은 지정하여 복사를 진행하는 것으로 추천한다.

만약 전체 파일을 진행하고자 한다면 COPY . /opt/server 명령을 통해 도커 파일기준 현재 디렉토리의 하위 폴더를 포함한 모든 파일을 도커의 /opt/server에 복사를 진행할 수 있다.

3. 서버 환경 설정

WORKDIR /opt/server
RUN pip3 install -r requirements.txt
RUN chmod +x /opt/server/start.sh

이제 실행 디렉토리를 지정하고, 서버 환경을 설정해 놓을 차례이다.

WORKDIR 을 통해 기본 실행 경로를 지정할 수 있다. 만약 WORKDIR을 지정하지 않으면 메인 루트 /에 있는 상태이기 때문에 RUN 명령의 실행 위치를 잡을 수가 없다. 따라서 꼭 지정이 필요하다. 그리고 RUN 명령을 통해서 추가적인 명령을 실행할 수 있는데 RUN 명령에 유의할 점을 RUN 명령은 도커 이미지를 제작하는 과정에 실행된다는 점을 이해해야 한다. 즉 Dockerfile을 생성 시점에 RUN 명령이 하넌 실행되고, Docker를 실행하는 시점에는 RUN 명령은 동작하지 않는다. 

4. 스크립트 실행

CMD ["/bin/sh", "-c", "start.sh"]

CMD는 Docker를 실행하는 시점에 동작하는 명령이다. 쉽게 설명하면 도커 이미지가 실행될 때 마다 이 CMD의 명령이 실행된다고 보면 된다. 그래서 그런지 1개의 커맨드만 지정이 가능하다.

 

따라서 만약 2가지 이상의 명령을 실행해야 하는 경우 스크립트를 작성하여 실행하는 것을 추천한다.

 

CMD 이외에 ENTRYPOINT라는 명령도 있는데 필자는 CMD를 추천한다.

start.sh 는 Bash 스크립트와 동일하게 작성을 진행하면 되고, 2개의 서비스 프로세스를 실행하고자 한다면 Docker의 경우 명령을 실행하면 해당 명령이 백그라운드 실행하여 프롬프트가 나타나게 되면, 실행하는 프로세스가 없는 것으로 판단하고 에러를 발생한다. 따라서 첫번째 프로세스는 nohup 명령을 이용해 백그라운드 실행으로 실행하고, 두번째 프로세스를 정상 실행하면 정상적으로 실행이 가능하다.

 

이렇게 만들어진 Dockerfile 전체는 다음과 같다.

FROM python:3.9

MKDIR /opt/server
MKDIR /opt/server/conf

COPY *.py /opt/server
COPY prod.cfg /opt/server/conf

WORKDIR /opt/server

RUN pip3 install -r requirements.txt
RUN chmod +x /opt/server/start.sh

CMD ["/bin/sh", "-c", "start.sh"]

Docker 빌드 및 저장소 업로드 

이제 만들어진 Dockerfile을 통해 Docker Image를 빌드할 차례이다.

아래와 같이 build 명령을 이용해서 손쉽게 빌드를 진행할 수 있다. image tag를 이용해 빌드된 이미지를 구분할 수 있으므로, 적당한 이름을 지어주도록 하자.

docker build -t (image tag) .

 

만들어진 이미지는 docker image ls 명령으로 확인이 가능하다.

Docker Hub에 로그인한 이후 docker push 명령을 통해서 내가 방금 만든 이미지를 업로드 할 수 있다.

Docker Hub는 계정내 디텍토리 유형으로 이미지를 관리할 수 있기 때문에 업로드할 경로를 지정하도록 하자.

docker login
docker image push <image tag> myname/myimage:<image tag>

Docker 서버에서 실행하기

이제 정상적으로 이미지까지 올라갔으니 서버에서 Docker를 내려 받고 실행하는 일만 남았다.

docker login

docker image pull <image tag> myname/myimage:<image tag>

정상적으로 내가 만든 이미지를 서버에서 다운로드를 받았다면, run 명령을 통해 실행할 수 있다.

docker run -d --name <image tag> <name>

-d 옵션은 백그라운드 실행을 의미한다.

만약 Docker Image에서 네트워크 서비스 포트를 사용한다고 하면, 도커를 실행하는 서버의 포트를 Docker Image와 실행 시점에 -p 옵션을 이용해 연결을 해줄 수 있다. 아래는 8080 포트를 Docker의 8888 으로 연결해주는 옵션이다.

docker run -d -p 8080:8888 --name <image tag> <name>

이상 간단하게 Dockerfile 생성부터 서버에서 실행하기까지 정리해 보았다. 추가적인 의견이나 잘못된 부분이 있다면 댓글 부탁.

반응형