Next.js 프로젝트를 S3과 CloudWatch를 사용하여 배포하지 않고, EC2에 띄운 뒤 도메인을 적용하여 배포
현재 상황
EC2 인스턴스는 Ubuntu 20.04 이미지를 사용
- FE 인스턴스 : Next.js 프로젝트를 pm2를 사용하여 background로 배포. Port는 3000
- BE 인스턴스 : Docker Hub에 배포된 Spring Boot 도커 이미지를, pull로 EC2에 받아와서 실행 중. port는 80
- AWS에서 도메인 주소 구입 및 BE 인스턴스에 연결 > 2023.06.21 - [Amazon Web Services(AWS)] - AWS] Route53 기초
4. CORS 문제 해결됨
목표: FE 인스턴스와 BE 인스턴스를 연결하고, 도메인을 사용하여 배포
1. EC2 Target Group 생성
Next.js 프로젝트 배포를 위한 설정.
현재 FE 인스턴스에서 Next.js 프로젝트는 port 3000 에서 실행되고 있으므로 3000을 작성한 뒤, "Include as pending below" 클릭 후 Create target group
2. EC2 Load Balancers 수정
HTTPS:443의 Forward target group을 1번에서 만든 target group으로 변경
3. 백엔드 서버 요청 url 변경
구매한 도메인이 www.ABC.com 이라고 가정하면, 기존에는 Backend 서버 요청 url을 www.ABC.com 으로 등록하였으나, 서버 요청 url을 BE 인스턴스 주소인 http://ec2-3-34-14-220.ap-northeast-2.compute.amazonaws.com 로 변경.
4. CI/CD
배포 방식은 다음 순서로 진행된다.
GitHub Action -> Docker Hub -> AWS EC2
Dockerfile
FROM node:16.13.2-alpine
# Directory 지정
WORKDIR /
# Install dependencies
COPY package.json ./
COPY yarn.lock ./
RUN yarn
# 필요한 모든 파일을 복사
COPY . .
# Build
RUN yarn add sharp
RUN yarn build
EXPOSE 3000
CMD ["yarn", "start"]
main.yml
주의사항: 맨 아래 line에서, 3000 포트 대신 80 등의 다른 포트로 포워딩하면 접속이 되지 않는다.
왜냐하면, 1번에서 port를 3000번으로 명시하였기 때문
sudo docker run -d --name ${{ secrets.PROJECT_NAME }} -p 3000:3000 ${{ secrets.DOCKERHUB_REPO_FE }}:latest
name: Next.js ci/cd
on:
push:
branches:
- main
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3
- name: Install and Build 🔧
run: |
yarn install
yarn build
## Docker
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: ${{ secrets.DOCKERHUB_REPO_FE }}:latest
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: connect EC2 instance and deploy docker images to Dev server
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.AWS_EC2_HOST_IP }}
username: ${{ secrets.AWS_EC2_USERNAME }}
key: ${{ secrets.AWS_SSH_KEY }}
# kill container -> remove container -> remove image -> pull new image -> run
script: |
sudo docker kill ${{ secrets.PROJECT_NAME }}
sudo docker rm ${{ secrets.PROJECT_NAME }}
sudo docker rmi ${{ secrets.DOCKERHUB_REPO_FE }}
sudo docker pull ${{ secrets.DOCKERHUB_REPO_FE }}:latest
sudo docker run -d --name ${{ secrets.PROJECT_NAME }} -p 3000:3000 ${{ secrets.DOCKERHUB_REPO_FE }}:latest
5. 위 방식의 문제점
- 프로젝트를 배포한 이후에 알게 되었으며, https인 Next.js EC2에서 http로 요청을 보내게 되면 오류가 발생한다.
- Developer Console에서 확인한 결과, "This request has been blocked; the content must be served over HTTPS" 라는 오류가 발생한다. 즉, 이미 https로 보안이 적용된 상태에서 보안이 더 낮은 상태로는 연결할 수 없다는 것이다.
- 이를 해결하기 위해, Next.js 프로젝트에서, Html <head> 부분에 아래 문구를 넣어 보았으나 여전히 오류 발생
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
내가 생각한 해결 방법
- https를 비활성화한다. 즉, Next.js 프로젝트 역시 http를 적용한다.
- 하나의 EC2 내에서, Next.js 와 Spring Boot 프로젝트를 모두 실행한다. 즉, Next.js EC2에서 Spring Boot도 Docker로 실행한다.
참고링크
Next.js Dockerfile: https://webruden.tistory.com/1060
Github action: 2023.06.09 - [CI-CD] - GitHub Action, Docker, EC2를 사용한 Spring Boot 프로젝트 배포 자동화
'Amazon Web Services(AWS)' 카테고리의 다른 글
AWS] Route53 기초 (0) | 2023.06.21 |
---|---|
AWS EC2] MySQL 설치 및 JVM Max heap space error 해결 (0) | 2023.06.09 |