현재 진행 중인 애완동물관련 프로젝트 백엔드 개발자에게 프론트엔드 배포를 맡아줄 수 있겠냐는 제안을 받았다. 배포 및 CI/CD라고는 딸깍 한 번이면 배포되는 vercel이나 firebase, gh-pages 등만 사용해봤기 때문에 AWS를 사용한 배포는 조금 많!이! 두려웠으나 도전해보기로 했다.

우선 백엔드 개발자가 이미 AWS IAM계정을 생성해주셨기 때문에 해당 계정 정보로 로그인 후 콘솔에서 진행하였다.
github repo를 클론하여 진행하려 했으나 docker를 통해 배포하는 게 어떠냐는 백엔드 개발자의 조언으로 docker image를 ecr에 업로드하여 진행하고자 한다.
배포 진행 과정은 다음과 같다.
1. EC2 인스턴스 생성 및 보안 자격 증명 엑세스 키 발급
2. ECR repository 생성
3. next.config standalone 옵션으로 프로젝트 build 최적화
4. docker image 생성 후 ECR repository에 push
5. EC2 인스턴스 연결 후 이미지 pull
인스턴스 생성 시에 신경써야 할 부분은 2가지
키페어 생성
: ssh를 통해 인스턴스를 로컬에서 연결할 것이기 때문에 키페어가 등록되어 있어야 한다. 키페어는 .pem으로 저장할 것
보안 그룹 생성

생성 후에 보안 자격 증명 액세스 키를 발급 받는다. 해당 키는 ssh를 통해 인스턴스(ubuntu) 접속 후 aws ecr 로그인 시 필요하다.
상단 네비게이션 바 우측을 보면 계정 정보를 자세히 볼 수 있는데, 하위 메뉴 중 보안 자격 증명을 선택해주면 된다.

스크롤을 내리다보면 나오는 액세스 키 발급 탭이 있는데 이 곳에서 새로운 액세스 키를 발급 받은 후 저장해주면 된다.
(나는 다른 곳에 적어두면 잊어버릴 것 같아서 csv 파일을 저장했다 ㅎ)

다른 것들과는 다르게 나도 손쉽게 할 수 있는 유일한 단계였다! ദ്ദി˙∇˙)ว
aws 콘솔에 접속 후, ECR(Elastic Container Registry) > repository 생성
리포지토리 생성에서 리포지토리 이름만 설정해주면 된다.
(그 외 설정은 무서워서 건드리지 않았다,,! ㅎㅎ)

standalone 옵션으로 프로젝트 build 최적화프로젝트 용량 이슈로 인해 standalone 옵션을 통해 진행했다.
해당 옵션은 배포 환경에서 웹앱을 실행할 때 필요없는 코드는 빌드 결과물에서 제외 시켜 결과적으로 이미지 크기를 줄여주고, 배포 시간을 단축 시켜준다.
module.exports = {
output: 'standalone',
}
npm run build
#root
.next
├ standalone
├ app
...
app
next.config.ts
...
여기서는 해야할 일이 많다. 굉장히 부지런하게 움직여야 하는 구간이다,,,

근면성실하게 커맨드를 복붙해보자,,^_^
standalone 옵션으로 build된 결과물로 이제 docker image를 생성해보자!
프로젝트 디렉토리에서 터미널을 실행 후 Dockerfile과 .dockerignore 파일을 생성해준다.
Dockerfile
# 빌드 스테이지
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY .env ./
COPY . .
RUN npm run build
# 실행 스테이지
FROM node:18-slim
WORKDIR /app
COPY --chown=node:node --from=builder /app/public ./public
COPY --chown=node:node --from=builder /app/.next/static ./.next/static
COPY --chown=node:node --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/standalone/node_modules ./.next/node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/.env ./
EXPOSE 3000
CMD ["node", "server.js"]
.dockerignore
.git
Dockerfile
node_modules
파일 작성이 완료되었다면 이제 터미널을 켜서 docker image를 생성해준다.
docker build -t <image명> .
만약 로컬에서 배포된 사이트를 테스트해보고 싶다면 아래 커맨드를 통해 확인해보자.
(아래 커맨드에서는 포트를 localhost:3000으로 연결시켜주고 있다.)
docker run -d -p 3000:3000 <image명(image id)>
그리고 이제 방금 갓 생성된 따끈따끈한 이미지를 ECR 로그인 후 푸시해준다.
그런데 ECR 로그인부터 참,,,힘들다,,,
aws-cli를 os에 맞게 설치 후, aws configure 설정이 필요하다.
aws configure 커맨드로 설정 시 default 값이 저장되고, aws configure --profile 커맨드로 설정 시에는 여러 값을 저장시켰다가 프로필을 골라서 사용 가능하다. 그리고 여기에서 1번 목차, 보안 자격 증명에서 발급 받은 키를 사용한다.
(나는 프로필에 저장해서 사용해야징~! ㅎㅎ)
aws configure --profile <profile name>
커맨드 입력 시 아래와 같은 문구가 차례대로 뜨는데 여기서 상단 2줄만 작성하면 된다.
AWS Access Key Id [None]:
AWS Secret Access Key [None]:
Default region name [None]:
Default output format [None]:
작성이 완료되었으면 이제 aws ecr 로그인을 드디어 할 수 있다,,,
aws ecr get-login-password --profile <profile name> --region <ecr region> | docker login --username AWS --password-stdin <ecr uri>
로그인 완료 시 login success라는 메세지를 받을 수 있다. 이제 생성한 도커 이미지를 ecr에 push해주면 된다
# 도커 이미지 태그
docker tag pet-diary-front <ecr uri>
# 이미지 푸시
docker push <ecr uri>
정말 먼 길을 돌고 돌아 마지막 단계다,,!!! 화이팅!!!!나 자신!!!!
1번 단계에서 생성한 ec2에 ssh로 연결해야한다.
ssh로 인스턴스 연결 시 발급 받은 키페어 저장 위치 경로를 적어줘야한다.
ssh -i <exam.pem> ubuntn@<public IPv4>
ubuntu 서버에 접속했다면 다시 서버 내에도 aws-cli/docker를 설치해줘야 한다.
sudo apt install unzip
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
그리고 aws configure를 다시 설정. 기억이 나지 않는다면 상단의 aws configure 설정을 보고 오자.
여기서 다시 aws ecr로그인을 해주자! 위와 살짝 다른 점은 sudo 명령어가 추가되었다는 점,,^_^
aws ecr get-login-password --profile <profile name> --region <ecr region> | sudo docker login --username AWS --password-stdin <ecr uri>
이제 aws ecr에 저장된 이미지를 pull 해주면,,,!!!
sudo docker pull <ecr uri>
드뎌 세팅,,,끝,,,!!!
.
.
.
.
.
인줄 알았으나 ㅎ
docker container를 실행해주어야 끝이 난다 ㅎ 하지만 얼마 남지 않았으니 힘,,내보자,,,
docker-compose파일을 추가하여 컨테이너를 생성하고자 한다.
(docker-compose 다운,,받아야한다,,,)
ubuntu 서버 내에 docker-compose.yml 파일 생성 후 작성은 아래와 같다.
touch docker-compose-exam.yml // 파일 생성 커맨드
vi ~/docker-compose-exam.yml //파일 읽기
i // 파일 작성/수정
// 도커 컴포즈 파일 복붙
esc
:wq // 파일 저장 후 수정 모드 나가기
docker-compose-exam.yml은 다음과 같이 작성했다 ㅎ,,
# docker-compose-exam.yml
version: '3.8'
services:
server:
image: <ecr uri>
ports:
- '3000:3000'
파일 작성이 끝나면 docker-compose up을 해주면 된다,,
(진짜-정말-최종-찐최종2-제발-끝3.ts)
sudo docker-compose -f pet-diary-front.yml up -d
docker compose 버전이 변경되면서 v2부터는 docker compose로 사용해주어야 에러가 나지 않는다,,^_^
그 후에 퍼블릭 IPv4나 퍼블릭 IPv4 DNS 주소에 포트번호를 추가 적용시켜주면 배포된 화면을 마주할 수 있따,,

드디어 멀고도 험한 여정이 끝이 났다,,,
사실 생략된 부분들(docker나 aws-cli 설치 등)이 좀 있지만,,,너무 길어서 생략할 수 밖에 없었던 점,,,모두들 이해하시리라고 믿어 의심치 않습니다,,,

진짜,,,개발자분들,,,다들 힘내시고,,,무탈한 코딩생활 즐기시길 바라요,,,,
이번에 작업하다가 백엔드 서버 날려버린 건 비밀,,, (백엔드 개발자님 정말 죽을 죄를 지었습니다,,제가 잘,,하겠슴ㄴ디ㅏ,,,)