앱 런칭 후 들어온 협업 제안, 그리고 AMI

우기·2024년 8월 7일
2
post-thumbnail
땅 따먹기와 걷기 앱을 결합한 그라운드 플립이라는 앱을 런칭했다.

여러 기술적 이슈들이 있었지만, 잘 극복 후 소수의 유저들을 대상으로 운영 중이다.

하지만 그저께 새벽,,,문의 단톡방에 아주 놀라운 채팅이 올라왔다.

자세한 내용은 밝힐 수 없지만 모종의 경로를 통해 우리 앱을 알게 되셨고, 정말 감사하게도 협업 문의를 주셨다.

약 1000 단위의 유저가 참여하고 2주간 진행되는 이벤트라고 하셨다.

그렇다면 우리 서버는 최악의 경우에 초당 1000개의 이상의 요청을 처리할 수 있어야한다.
하지만 아래와 같은 우리 앱의 특성 상 무작정 서버의 성능을 높이기엔 비효율적이었다.

  • 특정 시간(출퇴근 시간 등)에 트래픽이 몰릴 것으로 예상이 된다.
  • 다중 서버를 염두에 둔 분산락이 적용되어 있음.

이런 고민을 하던 중, AWS에서 EC2 인스턴스의 개수를 동적으로 늘릴 수 있는 Auto Scaling을 알게 되었고 이를 위해 AMI를 만들기로 했다.

현재 배포 시스템

약간은 이상하지만,, 호스트 머신에서 프로젝트 파일을 통째로 압축하고 이를 EC2에서 받아 다시 압축을 풀고 도커 이미지를 만들어 실행하는 구조다.

그렇다면 AMI는 어떤 식으로 만들어야할까?
지금 돌아가고 있는 서버를 그대로 AMI로 만든다고 해도 서버에서 새로운 변경사항이 생기면 이를 반영하지 못하는 문제가 생긴다.

즉, AMI가 실행될 때 '가장 최신의' 프로젝트 파일을 가져와 도커 이미지로 만들고 실행하는 과정을 거쳐야한다.

구상

내가 생각한 흐름은 다음과 같다.

  1. AMI를 사용해 인스턴스가 생성된다.
  2. 쉘 스크립트가 실행되어 S3에서 압축 파일을 가져온다.
  3. 압축 해제
  4. 이미지 생성 후 컨테이너를 실행

구현

그렇다면, 우선 서버에 aws cli를 설치한다.

다음은 쉘 스크립트를 작성한다.

echo "> remove current project file"
rm -rf /home/ubuntu/ground_flip

echo "> remove current log file"
rm -rf /home/ubuntu/logs/groundflip_log.log

echo "> get latest project file from s3"
sudo aws s3 cp s3://{bucket_name}/deploy/ground_flip.zip /home/ubuntu/ground_flip.zip

echo "> unzip project file"
unzip /home/ubuntu/ground_flip.zip -d /home/ubuntu/ground_flip

echo "> delete project zip file"
rm -rf /home/ubuntu/ground_flip.zip

이미지 생성 후 컨테이너를 띄우는 과정은 프로젝트 폴더 내에 deploy.sh에 있어 이를 재활용하기로 했다.

#!/usr/bin/env bash

APP_NAME="ground_flip"
REPOSITORY=/home/ubuntu/ground_flip

echo "> Check the currently running container"
CONTAINER_ID=$(docker ps -aqf "name=$APP_NAME")
pwd
ls
if [ -z "$CONTAINER_ID" ];
then
  echo "> No such container is running."
else
  echo "> Stop and remove container: $CONTAINER_ID"
  docker stop "$CONTAINER_ID"
  docker rm "$CONTAINER_ID"
fi

echo "> Remove previous Docker image"
docker rmi "$APP_NAME"

echo "> Build Docker image"
docker build -t "$APP_NAME" "$REPOSITORY"

echo "> Run the Docker container"
docker run -d -p 8080:8080 --env-file /home/ubuntu/ground_flip/.env -e TZ=Asia/Seoul -v /home/ubuntu/logs:/logs --name "$APP_NAME" "$APP_NAME"

이제 AMI를 만들고 시작 템플릿을 만들면 된다.

원하는 인스턴스에서 이미지 생성을 선택한다.

이제 생성된 이미지로 시작 템플릿을 만든다.

자잘한 항목들은 필요에 따라 선택하면 되지만, 아래 사진들에서 보다시피 적절한 IAM 역할을 부여해야 S3 접근, Cloudwatch로 로그 전송 등이 가능하다.

마지막으로, 사용자 데이터를 입력해 인스턴스가 생성될 때 실행할 명령어들을 기재한다.

나는 프로젝트 파일을 가져와 압축을 푸는 on_start.sh와 도커 이미지 생성 후 컨테이너를 띄우는 deploy.sh를 실행하게끔 했다.

해당 시작 템플릿으로 인스턴스를 생성 후 docker ps를 입력하면 아래와 같이 컨테이너가 동작 중인 것을 볼 수 있다.

profile
항상 한번 더 생각하는 개발자를 지향합니다!

0개의 댓글