Dockerfile은 왜 사용하는걸까요? 우리가 앞에서 배웠던 것처럼, Docker engine으로 ubuntu 컨테이너를 생성해서 SSH(Secure Shell)로 접속을 해서 개발을 진행하면 될 수 있지 않을까요?
이 질문에 대한 답은 약 3가지로 추려볼 수 있겠네요.
직접 SSH로 접속해서, 명령어를 입력해야하므로 불편합니다. 반면 Dockerfile은 docker build 딸.깍 하면 되버리죠.
Docker는 Layer라는 개념을 사용하는데 SSH로 접속해서 이것저것 설치하게 되면, 엄청 커지게 됩니다. 반면에 Dockerfile은 각 명령어(RUN, COPY)가 하나의 층으로 쌓입니다. 만약 소스코드 한줄만 수정했다면, Docker는 OS나 라이브러리 설치는 건너뛰고 수정된 Layer만 다시 빌드합니다. 당연히 속도가 훨씬 빠르겠죠?
현대 개발체계에서는 컨테이너를 수정해서 사용하는게 아니라, 버리고 새로 만드는것을 원칙으로 합니다. 만약 컨테이너 내부 설정을 내 마음대로 설정하거나, 위에서처럼 이것저것 설치하다보면 이 구조는, 나만 아는 복잡한 구조가 됩니다. 이를 Snowflake Server라고 하는데, Dockefile은 그냥 build 하면 됩니다.
🪜 Dockerfile을 작성하기 전에 해야하는 것
Dockerfile을 작성해서, build하기 위해서는 우리가 작업하는 프로젝트가 있어야합니다. 뭐 예를 들어 웹사이트를 만들거나, 백엔드 API를 만드는 등의 프로젝트를 해야하는데, 거창한 프로젝트를 하자니 이번 실습이 길어지므로 간단하게 Python의 FastAPI를 사용해서 실습을 진행해도록 합시다.
FastAPI를 사용하는 방법은 차차 다른 포스팅에서 설명하겠지만, 일반적으로 MLOps에서 가장 많이 사용되는 라이브러리입니다.(Flask, Django도 많이 사용되긴하지만, 요즘은 Async를 사용하는 FastAPI의 인기가 좋다고 합니다!)
1️⃣ Python 3.11 설치
Terminal window
pxxguin@root:~$
brewinstallpython3.11
이 코드 하나면, MacOS에서 python을 설치하는건 끝납니다.
2️⃣ Python 가상환경 만들기
Terminal window
pxxguin@root:~$
mkdirmyfirstapp
pxxguin@root:~$
python3.11-mvenv.venv
pxxguin@root:~$
source.venv/bin/activate
원래 Python뿐만 아니라, 여러 언어에서 버전관리가 굉장히 중요해서 poetry나 uv를 자주 사용하지만, uv나 poetry를 사용할 경우에 Dockerfile에서 uv나 poetry를 설치하는 명령어가 추가되어 다소 복잡할 수 있을 것 같아 버전관리를 신경쓰지 않았습니다.
3️⃣ 가상환경에서 필수 라이브러리 설치하기
Terminal window
pxxguin@root:~$
pipinstalluvicornfastapi
FastAPI를 사용하기 위해서 반드시 필요한 라이브러리가 uvicorn입니다. 자세한 사용법은 다른 포스팅에서 설명할게요.
4️⃣ FastAPI 코드 작성하기
main.py
1
from fastapi import FastAPI
2
3
app = FastAPI()
4
5
@app.get('/')
6
asyncdefroot():
7
return {"message":"Hello, MLOps!"}
위와 같은 코드를 작성하게 되면, 준비는 모두 끝났습니다.
TIP
혹시, 어려워하실 분들을 위해서 FastAPI의 기본 디렉토리 구조를 첨부합니다.
Terminal window
pxxguin@root:~$
my-fastapi-app/
pxxguin@root:~$
├──src/
pxxguin@root:~$
│└──myfirstapp/
pxxguin@root:~$
│└──main.py# FastAPI 앱 객체(app)가 있는 곳
pxxguin@root:~$
├──Dockerfile# 도커 빌드 설정 파일
pxxguin@root:~$
└──requirements.txt# 가상 환경 설정
requirements.txt의 경우 pip freeze > requirements.txt를 작성하게 되면 자동으로 생성됩니다!
여기서 -d는 Detach의 약자로 해당 컨테이너를 백그라운드에서 실행시키겠다는 의미입니다. 앞서 -it의 옵션과 비교했을때 대화형 인터페이스가 실행되지 않는것을 볼 수 있습니다.
-p의 경우 포트를 적어주는 부분인데 아까 CMD 명령어 부분에서 —port를 8000으로 설정했잖아요? 이게 컨테이너의 포트 8000번을 열어준다는 의미인데, HostOS에서 이 컨테이너에 열린 포트로 접근하려면 8000:8000으로 설정해야겠죠? HostOS포트포트입니다. HostOS는 변해도 상관없는데, Docker포트의 경우 앞에서 8000으로 지정했기때문에 반드시 8000으로 작성해야합니다.
🥱 마무리
이제 마지막으로 터미널창에 아래 명령어를 작성해보죠.
Terminal window
pxxguin@root:~$
curl-XGEThttp://localhost:8000|jq
pxxguin@root:~$
# 실행결과
pxxguin@root:~$
# % Total % Received % Xferd Average Speed Time Time Time Current