FastAPI 프로젝트 Docker + EC2 배포하기

소원·2024년 10월 6일

2024

목록 보기
8/10
post-thumbnail

1. 서론

현재 진행중인 프로젝트는 2개의 백엔드 서버를 개발해 사용하고 있습니다.

  • Springboot : Frontend로부터 오는 통신 요청을 처리하고 응답처리
  • FastAPI : 훈련시킨 AI모델의 API 엔드포인트를 제공

어떤 과정으로 배포를?

EC2에 2개의 인스턴스를 생성해 각각의 서버를 따로 배포할 예정입니다.
따라서 NginX와 같은 웹서버를 따로 필요로 하지 않고,
Docker로 각각의 서버를 이미지로 만든 후 EC2에서 pull받아 실행하려고 합니다.

왜 이 방법으로?

Github Action을 써서 멋지게 CI/CD...구현하고 싶었으나,
.env나 .yml처럼 git에 올라가지 않는 친구들을 처리하기 귀찮았습니다.
사실 workflow로 secretKey 어쩌구 하면 되는 것 같긴 했어요.

FastAPI 서버의 경우, model을 포함하고 있습니다.
이 AI모델 선생님이 모델치고 별로 크지 않다고 생각했지만 별로 컸습니다.
git에 올릴 수 없어서 Docker를 사용하고자 했습니다.

이 또한 S3를 이용하면 가능하나 그냥 이 방법으로 해보기로 했습니다.
그냥.

2. Build하기 전 필요한 것?

Docker 회원가입

: 저는 Docker Desktop가 설치되어있는 상태였습니다.

Build하고 싶은 프로젝트에 DockerFile만들기

: 현재 FastAPI를 예시로 들고있기 때문에 제가 작성한 DockerFile을 가져왔습니다.

FROM python:3.10.7
RUN ln -snf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
RUN echo Asia/Seoul > /etc/timezone
COPY . /AI
WORKDIR /AI
RUN pip install --upgrade pip
RUN pip install -r requirements.txt #미리 만들어두기
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Q. 파이썬 버전은?
-> 프로젝트에서 사용중인 python 버전으로.. 제 경우는 local에서는 가상환경을 열어서 테스트했기때문에 그 버전으로 적었습니다.
Q. 왜 . /AI인가요?
->프로젝트 폴더명이 AI이여요.

Q. requirements.txt는 뭔가요?
프로젝트를 실행하는 터미널에서 만들어주면 됩니다.

pip freeze > requirements.txt

같이하는 사람들과 설치 버전까지 맞춰야지 오류안나고 좋잖아요?
만든 requirements.txt를 EC2에도 깔아줘야하니까 저렇게 작성합니다.

.dockerignore만들기

.gitignore 처럼 가상환경이나 .git이나 빼고싶은 것 빼세요.
위에 사진 보면 Dockerfile이랑 .dockerignore도 보이죠? 저렇게 그냥 냅다 넣어두시면 된답니다?

프로젝트 폴더에서 CMD켜기


이여자는 왜 경로가 이렇게 짧냐?
하시면 다음 글을 봐주세요.

3. Docker Image Build & Push

Docker Login하기

docker login

Docker Desktop을 키고있거나 이미 로그인 한적이 있다면 알아서 로그인 됩니다. 짱.

Docker Image build

띄어쓰기를 주의하세요.. 이미지 이름과 . 사이

docker build -t {이미지 이름} .

새로 빌드해야하는김에 초반 사진을 가져왔어요.

그냥 Springboot의 경우 1분만에 끝나는데, 우리의 FastAPI서버는 3시간이 걸립니다. Wow

Build 확인

docker images

목록에 방금 생성한 이미지 이름으로 있어야합니당.

Tag 붙여주기

docker tag {이미지 이름} {내 ID}/{원하는 이름}

Docker Image Hub에 Push하기

docker push {내 ID}/{원하는 이름}

방금 Tag붙인 그대로 해주면 됩니다
그럼 또 올리는데 3-40분이 걸려요.Wow

Push 확인

docker search {내 ID}/{원하는 이름}

Name에 {내 ID}/{원하는 이름} 그대로 떠야지 있는거랍니다?

4. Pull하기 전에 필요한 것?

EC2 인스턴스 생성

아 다른 곳에서 적을래요 알아서 만드셈.ㅋ

EC2 인스턴스 접속

Window에 Ubuntu Linux없어서 그냥 EC2 내에서 실행합니다.
그럼 ssh 접속할 필요도 없어요. 굿.

5. Docker Image Pull

지금부터는 EC2 console에서 합니다

Ubuntu에 Docker 설치

sudo apt update -y

sudo apt install docker.io -y

sudo systemctl start docker

sudo systemctl enable docker

sudo usermod -aG docker ubuntu

newgrp docker

위의 6줄은 실행시 아무 내용도 출력되지 않으니 연달아 작성하세요.
참고로 EC2는 복붙이 안됩니다.
저처럼 인스턴스 900개 만들면 자동으로 작성이 가능한 경지에 오릅니다. 정진하세요.

Docker Image Hub에서 Pull하기

docker pull {내 ID}/{원하는 이름}

당연히 동일한 이름이어야지 원하는 이미지가 다운되겠죠? 당연하죠.

Pull 확인

docker images

5. Docker Image 실행

Docker Image 실행

docker run -d -p 8000:8000 {내 ID}/{원하는 이름}

예시가 FastAPI라 포트번호가 8000입니다. Springboot하고 있으면 8080하면 됩죠.

Docker Image 실행 확인

docker ps

방금 전 실행한 이미지가 나와야합니다. 가장 처음의 containerID가 너무 중요합니다 기억해요.

근데 없다면?
오류나서 나서 종료 된걸 겁니다...
1)종료된 containerID를 확인합니다.
docker ps -a
2)왜 종료됐는지 로그를 확인합니다.
docker logs {containerID}
3)코드를 고쳐요.밑에 container 삭제도 해주세요.
4)한번 울고 처음부터 다시 시작하면 됩니다. 으앙.

잘 작동하는지 Log출력

docker logs -f {containerID}

containerID 되게 긴데 복붙 안돼서 잘 입력하셔야해요.
하다보면 매크로방지 보안문자같아서 티켓팅 연습에 도움이 되는 것 같아요.

-f를 통해 실시간으로 log를 확인할 수 있으니 잘 작동하는지 테스트해보시면 됩니다.

Docker Container 종료하기

docker stop {containerID}

다 사용했으면 멈춥니다.

docker ps -a

종료된 container를 확인해주세요.

Docker Container와 Image 삭제하기

docker rm {containerID}

Container 지워집니다.

docker rmi {imageID}

imageID뭐냐구요? docker images해서 확인하세욥.

0개의 댓글