Dockerfile이 무엇인지 알아보기 전에, 작은 실험을 해보겠습니다. 이전 섹션에서 가져온 Python 이미지를 기억하시나요? 먼저 docker run -it 명령어를 사용하여 컨테이너에 접속해 봅시다. -it 파라미터가 무엇을 하는지 기억하시나요? 컨테이너에 가상 터미널(pseudo-TTY)을 할당하여 사용자가 상호작용할 수 있게 해줍니다. 컨테이너 안에 들어간 후, 현재 디렉토리의 모든 파일을 나열해 보겠습니다:
[root@novita ~]# docker run -it python:3.7 /bin/bash
root@692f87774bf7:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@692f87774bf7:/#
다음으로 hello.py라는 파일을 생성한 후, 다시 모든 파일을 나열해 보겠습니다:
root@692f87774bf7:/# touch hello.py
root@692f87774bf7:/# ls
bin boot dev etc hello.py home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
hello.py가 생성된 것을 확인할 수 있습니다. 이제 컨테이너를 종료하고, 동일한 docker run -it python:3.7 /bin/bash 명령어로 다시 컨테이너의 대화형 모드에 진입한 후 모든 파일을 나열해 보겠습니다:
root@692f87774bf7:/# exit
exit
[root@novita ~]# docker run -it python:3.7 /bin/bash
root@65c767655e8a:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@65c767655e8a:/#
아마 문제점을 눈치채셨을 겁니다. 이상하게도 우리가 이전에 만들었던 파일이 사라져 있습니다.
이는 컨테이너 내에서 수행한 작업이 이미지를 변경하지 않기 때문입니다. 컨테이너는 이미지 위에 쓰기 가능한 레이어만 추가할 뿐입니다. 마치 서예 템플릿 위에 트레이싱 페이퍼를 올려놓은 것과 같아서, 트레이싱 페이퍼에 무엇을 쓰든 아래 레이어에는 영향을 미치지 않습니다. 이 기능은 VM 스냅샷과 다소 비슷합니다.
하지만 문제가 있습니다. 컨테이너 내에서의 작업이 이미지를 변경하지 않는다면, 코드를 배포할 때마다 특정 작업을 반복하지 않고도 빠른 배포를 어떻게 할 수 있을까요? 그렇게 하면 상당히 비효율적일 것입니다.
여러분이 소셜 미디어 플랫폼의 기술 책임자이고, 갑자기 바이럴 이벤트가 발생하여 대규모 사용자 트래픽을 처리하기 위해 수백 대의 클라우드 서버를 신속하게 확장해야 한다고 가정해 보겠습니다. 여러분의 팀은 애플리케이션 배포를 위해 Docker를 선택했습니다. 위의 방법을 사용하여 배포한다면 사용자들은 실망할 것입니다. 서비스가 복구될 때쯤이면 사용자들은 이미 다른 곳으로 떠나버렸을지도 모릅니다.
여기서 Dockerfile이 등장합니다. Docker 공식 소개에 따르면:
Docker는 Dockerfile의 지침을 읽어 자동으로 이미지를 빌드할 수 있습니다. Dockerfile은 사용자가 이미지를 조합하기 위해 명령줄에서 호출할 수 있는 모든 명령이 포함된 텍스트 문서입니다. docker build를 사용하면 여러 명령줄 지침을 순차적으로 실행하는 자동 빌드를 생성할 수 있습니다.
간단히 말해, Dockerfile은 이미지를 빌드하는 데 필요한 모든 명령이 포함된 텍스트 문서입니다. 마치 블록 세트를 원하는 이미지로 조립하기 위한 설명서와 같습니다.
이제 실용적인 시나리오를 통해 Dockerfile을 구성하는 방법을 알아보겠습니다. Python 이미지를 예로 들어 보겠습니다. 제 로컬 머신(컨테이너 외부)에는 Optimal_Hotel_Matching.py라는 Python 스크립트가 있습니다. 이 스크립트는 웹 스크래핑 프로그램입니다. 컨테이너 안에서 실행해 보겠습니다:
예상대로 오류가 발생합니다. Python 이미지에 requests HTTP 라이브러리(서드파티 모듈)가 설치되어 있지 않기 때문입니다. 이는 의존 환경을 설정해야 하는 일반적인 시나리오입니다. Dockerfile을 사용하여 이 문제를 해결해 보겠습니다.
첫 번째 Dockerfile을 작성하기 전에, 몇 가지 일반적인 Dockerfile 명령어를 알아보겠습니다:
FROM: 빌드의 기본 이미지를 지정합니다.MAINTAINER: 이미지 작성자의 이름과 이메일을 설명합니다.RUN: Dockerfile에서 가장 중요한 명령어 중 하나입니다. 컨테이너에서 명령을 실행하고 결과를 커밋합니다.CMD: 컨테이너가 시작될 때 실행할 명령을 지정합니다.COPY: 호스트에서 컨테이너의 파일 시스템으로 파일을 복사합니다.WORKDIR: Dockerfile에서 이후에 오는RUN,CMD또는ENTRYPOINT명령의 작업 디렉토리를 설정합니다.
이제 첫 번째 Dockerfile을 작성하여 요구 사항을 해결해 보겠습니다: requests 라이브러리를 설치하고 스크립트를 실행합니다.
다음과 같은 해결책이 있습니다:
FROM python:3.7 # 기본 이미지를 python:3.7로 지정
MAINTAINER ultra "tech@novita.ai" # 이미지 작성자의 이름과 이메일
RUN pip install requests # requests 라이브러리 설치
WORKDIR /dockerfileTest # 작업 디렉토리 설정
COPY . . # 현재 디렉토리 내용을 컨테이너로 복사
CMD ["python", "Optimal_Hotel_Matching.py"] # 스크립트 실행 명령
위 내용을 프로젝트 디렉토리에 Dockerfile이라는 파일로 저장합니다.
이제 docker build 명령어를 사용하여 이미지를 빌드하고, 쉽게 식별할 수 있도록 태그를 지정합니다:
[root@novita dockerfileTest]# docker build --tag python:requests .
Sending build context to Docker daemon 5.12 kB
...
빌드가 완료된 후 docker images 명령어로 확인합니다:
[root@novita dockerfileTest]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python requests 04f20acdc288 2 hours ago 926 MB
...
requests 태그가 지정된 새로운 Python 이미지가 로컬에 생성된 것을 확인할 수 있습니다. 이 이미지를 실행하여 No module named 'requests' 오류가 사라지고 프로그램이 예상대로 실행되는지 확인해 보겠습니다.
[root@novita dockerfileTest]# docker run python:requests
Computing distance between 116.368816,39.866464 and 116.438946,39.921624
Computing distance between 116.370910,39.869603 and 116.438946,39.921624
...
성공했습니다! 컨테이너가 코드를 실행하고 종료되었습니다.
이것이 끝일까요?
이 글에서는 Dockerfile의 간단한 적용 방법을 공유했습니다. 실제 기업 프로덕션 환경에서는 Dockerfile이 더 복잡한 경우가 많습니다.
Novita AI 는 여러분의 AI 야망을 실현하는 올인원 클라우드 플랫폼입니다. 원활하게 통합된 API, 서버리스 컴퓨팅, GPU 가속을 통해 AI 기반 비즈니스를 빠르게 구축하고 확장할 수 있는 비용 효율적인 도구를 제공합니다. 인프라 문제를 해결하고 무료로 시작하세요 – Novita AI가 여러분의 AI 꿈을 현실로 만들어 드립니다.
추천 자료:
