안녕하세요. Gameeye에서 deeplol.gg 서비스를 개발 중인 김철기입니다.
클라우드 서버 인프라 구축, 백엔드 개발, 딥러닝 모델 연구를 담당하고 있습니다.
해당 포스팅은 Style Transfer deeplearning 모델을 웹으로 서비스해보는 시리즈의 3편입니다. 3편에서는 구현한 페이지를 CI/CD를 적용하여 배포하는 기능을 구현합니다. 페이지를 작성하는 내용은 1편에 모델의 결과를 반환하는 API 구현은 2편에 있으니 참고하시길 바랍니다.
시리즈
최종 결과
서비스 사용해보기(서버비용 이슈로 사용종료)
Github 코드 보기
자세한 내용을 설명하기 전 어떤 서비스를 활용하여 파이프라인을 구축할 것인지 간단하게 설명드립니다.
앱을 배포하는 파이프라인은 다음과 같습니다.
- 코드 작성: 로컬에서 코드가 작성됩니다.
- Github Commit: 작성한 코드를 Commit 합니다.
- Github Action: Commit된 코드를 작성한 yaml 파일 명세에 맞게 Test 및 Integration 후 Deployment합니다.
- AWS Beanstalk: 전달받은 코드와 Dockerfile로 환경을 구축한 뒤 앱을 실행시킵니다.
해당 포스팅에서 설명드릴 내용은 3번과 4번입니다. 1, 2번에 해당하는 내용인 Github 명령어에 대해서는 자세히 다루지 않습니다.
AWS Beanstalk 플랫폼에서 동작할 Dockerfile을 작성합니다.
python 3.8 환경에서 필요한 라이브러리를 설치한 후 CMD로 uvicorn 명령어를 실행시킵니다.
*주의: FROM으로 시작하는 첫번째 줄에 AS를 사용하는 경우 현재 AWS Beanstalk Docker 플랫폼에서 에러를 발생시킵니다.
# ------------------------------------------------------------------------------
# Base image
# ------------------------------------------------------------------------------
FROM python:3.8-slim
# ------------------------------------------------------------------------------
# Install dependencies
# ------------------------------------------------------------------------------
FROM python:3.8-slim AS deps
COPY requirements.txt ./
RUN apt update > /dev/null && \
apt install -y build-essential && \
pip install --disable-pip-version-check -r requirements.txt
# ------------------------------------------------------------------------------
# Final image
# ------------------------------------------------------------------------------
FROM python:3.8-slim
WORKDIR /usr/src/app
COPY . /usr/src/app
COPY --from=deps /root/.cache /root/.cache
RUN pip install --disable-pip-version-check -r requirements.txt && \
rm -rf /root/.cache
EXPOSE 5000
# CMD ["gunicorn", "--preload", "-c", "gunicorn.conf.py", "app.main:create_app()"]
CMD ["uvicorn", "app.main:app", "--reload", "--host=0.0.0.0", "--port=5000"]
Github Action이 동작할 때 실행되는 yaml 명세를 작성합니다.
앱을 Test하는 yaml 파일입니다. master 브랜치에 PR이 발생하면 python 3.8 환경에서 필요한 라이브러리를 설치 후 pytest로 Test합니다.
on:
pull_request:
branches:
- master
jobs:
deploy:
name: App Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v1
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Test
run: |
pytest -v
작성된 코드를 통합해 s3에 push하는 CI 파트와 새로운 코드로 환경을 업데이트하는 CD 파트로 구성됩니다.
Github의 secrets aws 키값을 미리 환경 변수로 설정해주셔야 합니다.
settings -> secrets -> actions 에서 설정할 수 있습니다.
name: AWS-BeanStalk-Pipeline
env:
APP_S3_BUCKET_NAME: elasticbeanstalk-ap-northeast-2-xxxxxxxxx
APP_NAME : ironkey-project-transfer-style
ENV_NAME: Ironkeyprojecttransferstyle-env
DEPLOY_PKG_NAME: github-action-ironkey-project-transfer-style_${{ github.sha }}.zip
AWS_REGION_NAME: ap-northeast-2
on:
push:
branches:
- master
jobs:
ci_part:
runs-on: [ubuntu-latest]
steps:
- name: Clone this repositary
uses: actions/checkout@v2
- name: Make zip pkg
run: zip -r ${{ env.DEPLOY_PKG_NAME }} ./ -x *.git*
- name: Config Access to AWS
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS }}
aws-secret-access-key: ${{ secrets.AWS_SECRET }}
aws-region: ${{ env.AWS_REGION_NAME }}
- name: push to S3
run: aws s3 cp ${{ env.DEPLOY_PKG_NAME }} s3://${{ env.APP_S3_BUCKET_NAME }}/
- name: Print msg
run: echo "CI part is finished"
cd_part:
runs-on: ubuntu-latest
needs: [ci_part]
steps:
- name: Config Access to AWS
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS }}
aws-secret-access-key: ${{ secrets.AWS_SECRET }}
aws-region: ${{ env.AWS_REGION_NAME }}
- name: Create new App Version
run : |
aws elasticbeanstalk create-application-version \
--application-name ${{ env.APP_NAME }} \
--source-bundle S3Bucket="${{ env.APP_S3_BUCKET_NAME }}",S3Key="${{ env.DEPLOY_PKG_NAME }}" \
--version-label "Ver-${{ github.sha }}" \
--description "SHA-${{ github.sha }}"
- name: Deploy new App Version
run : aws elasticbeanstalk update-environment --environment-name ${{ env.ENV_NAME }} --version-label "Ver-${{ github.sha }}"
- name: Print msg
run : echo "CD part is finished"
앱이 실행된 aws 환경을 생성합니다.
aws console -> 새 환경 생성 버튼 클릭 -> 웹 서버 환경 선택
환경 이름 작성 -> 플랫폼을 Docker, 플랫폼 버전을 최신으로 설정 후 추가 옵션 구성 클릭
인스턴스 용량 16GB로 설정(용량이 적으면 구성에 실패할 수 있습니다.)
용량 설정에서 인스턴스 유형을 c5a.xlarge로 설정(낮은 스펙의 서버를 선택하면 구성에 실패할 수 있습니다.)
마지막으로 환경 생성 버튼을 클릭하면 환경이 생성되기 시작합니다.
환경이 생성될 때 콘솔이 동작하는데 거기서 s3 버킷이 나오는 부분을 저장해둡니다.
저장해 둔 버킷 경로를 Dockerflie 아래 부분에 채워줍니다.
APP_S3_BUCKET_NAME: elasticbeanstalk-ap-northeast-2-xxxxxxxxx
환경이 생성되면 APP_NAME과 ENV_NAME도 알맞게 채워줍니다.
Dockerfile까지 수정완료하고 Github에 코드를 commit, push해주면 Github Action을 통해 deploy.yaml 파일이 실행되는 것을 확이할 수 있습니다.
환경에 배포가 완료되면 Beanstalk에 상태가 아래 이미지처럼 변합니다.
마지막으로 좌측 메뉴탭 -> 환경으로 이동을 누르면 작성한 페이지가 배포된 것을 확인할 수 있습니다.
페이지가 잘 동작하는지 확인!
시리즈에 포함된 포스팅 3편을 통해 간단한 페이지 구성부터 모델의 결과값 추출, CI/CD까지 진행을 해보았습니다. 기본적인 python, deeplearning, 서버 지식이 있다고 가정하고 작성한 포스팅이어서 설명이 많이 불친절했던것 같습니다. 너무 내용이 빈약해 이해가 어려운 부분은 피드백 주시면 조금씩 더 채워넣도록 하겠습니다. 부디 많은 분들에게 도움이 되었으면 좋겠네요. 향후 Style Transfer Model을 조금 더 고도화해서 사용하는 내용 또는 관련 논문을 리뷰가 해당 시리즈에 포함될 수 있을것 같습니다.
부족한 포스팅 지금까지 읽어주셔서 감사합니다!