# Situation 상황
사내에서 DRF로 개발하고 있으며, Github Action과 AWS ECR, ECS를 활용해서 배포를 하고 있다. Github Action에서 배포 실행 버튼을 누르면 아래와 같은 순서로 배포가 진행되었다.
1. 선택한 브랜치의 코드를 바탕으로 도커 이미지 생성해서 ECR로 이미지 업로드
2. 1번에서 업로드한 ECR 이미지로 API 서버, 워커 서버 등 배포 진행
# Task 과제
1번이 프로젝트가 커지고 외부 라이브러리나 팩키지 설치가 많아질수록 속도가 오래 걸렸다. 특히 PostGIS를 쓰게 됨에 따라 관련 해서 우분투에 libgdal-dev 팩키지 설치가 필요해졌는데 이 팩키지 설치만 몇 십초 씩 걸려 긴 시간이 소요되었다. 어떻게든 속도 개선 작업이 필요했다.
# Action 행동
1. requirements.txt를 테스트 관련 팩키지 등을 제외하고 필수 팩키지만 남긴 requirements.base.txt로 분리한다.
2. develop으로 작업 브랜치를 병합할 때 requirements.base.txt와 DockerfileBase의 변경 사항이 있을 경우 베이스 도커 이미지를 미리 만든다.
3. 배포 때 미리 만든 베이스 도커 이미지를 사용해서 팩키지 설치 시간을 절약한다.
# Result 결과: 17.65% 배포 속도 개선
실제 Production 기준 8분 30초 걸리던 배포가, 7분 걸려 1분 30초를 절약할 수 있었다. 510초 -> 420초로 원래 시간 대비 (510-420)/510 × 100 ≒ 17.65% 개선되었다.
코드 예
DockerfileBase
FROM ubuntu:22.04
ARG PROJECT_PATH=app
RUN mkdir $PROJECT_PATH
ADD ./commons/requirements.base.txt /$PROJECT_PATH/
WORKDIR $PROJECT_PATH
RUN apt-get update && apt-get install -y python3 python3-pip libgdal-dev gettext
RUN ln -s /usr/bin/python3 /usr/bin/python
RUN pip install --upgrade pip
RUN pip install -r requirements.base.txt
RUN rm -r /$PROJECT_PATH/
create-base-docker.yaml
name: Create base docker image
on:
push:
branches:
- develop
paths:
- deploys/DockerfileBase
- commons/requirements.base.txt
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ap-northeast-2
jobs:
create-base-docker-image-to-ecr:
runs-on: ubuntu-latest
steps:
- run: echo "Creating a Base Docker Image"
- run: |
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY
echo $AWS_REGION
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build Image
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: taptorestart/backend-base
IMAGE_TAG: latest
run: |
docker build -f deploys/DockerfileBase -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
Dockerfile
실제 배포 때 사용할 도커 이미지를 만들 때 기존에 만든 베이스 도커 이미지를 사용한다. 이미 필수 팩키지가 다 설치된 이미지를 사용하므로 팩키지 설치 시간이 절약된다.
FROM ECR_REGISTRY/taptorestart/backend-base:latest
...