AWS 배포 자동화 구성하기

mminjg·2022년 11월 6일
7
post-thumbnail

이 글은 다음 두 글을 합친 버전입니다. 내용의 차이는 없습니다.
https://velog.io/@mminjg/AWS-S3-HTTPS-정적-웹-사이트-호스팅-및-배포-자동화
https://velog.io/@mminjg/Github-Actions-CodeDeploy를-이용한-EC2-배포-자동화

프론트엔드는 AWS S3에서 정적 웹 사이트 호스팅을 하고, CloudFront 배포로 웹 사이트를 제공하고자 한다.

도메인 등록

Route 53에서 도메인을 구매하였다.

HTTPS 정적 웹 사이트 호스팅

버킷 생성

도메인 이름 버킷 생성

S3 > 버킷 > 버킷 만들기

버킷 이름은 도메인과 같아야 한다.

퍼블릭 액세스 차단 비활성화

퍼블릭 액세스 차단을 비활성화 설정한다.

버킷 정책 편집

버킷 > 권한 > 버킷 정책 편집

{
    "Version": "2012-10-17",
    "Id": "Policy1608529503037",
    "Statement": [
        {
            "Sid": "Stmt1608529502358",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-tcat.com/*"
        }
    ]
}

다음과 같이 입력하여 정책을 편집한다.

정적 웹 사이트 호스팅 활성화

버킷 > 속성 > 정적 웹 사이트 호스팅 편집

정적 웹 사이트 호스팅을 활성화하고 인덱스 문서와 오류 문서에 index.html을 입력한다.

파일 업로드

확인을 위해 리액트 빌드 파일을 업로드 한다.

서브 도메인 버킷 생성

퍼블릭 액세스 차단 비활성화, 버킷 정책 편집은 위와 동일하다.

정적 웹 사이트 호스팅 리디렉션 설정

정적 웹 사이트 호스팅을 활성화하고 호스팅 유형을 객체에 대한 요청 리디렉션으로 설정한다. 호스트 이름을 입력하고 https를 선택한다.

SSL 인증

https 설정을 위해 SSL 인증서를 발급받아야 한다. CloudFront를 이용하기 위해서는 꼭!!! 리전을 버지니아 북부로 설정해야 한다.

Certificate Manager 인증서 요청

AWS Certificate Manager > 인증서 > 인증서 요청

'Route 53에서 레코드 생성' 버튼을 누른다.

Route 53 > 호스팅 영역 에서 레코드를 확인할 수 있다.

CloudFront 배포

CloudFront는 AWS에서 제공하는 CDN 서비스이다. CloudFront는 엣지 로케이션이라고 하는 데이터 센터의 전 세계 네트워크를 통해 콘텐츠를 제공하는데, CloudFront를 통해 서비스하는 콘텐츠를 사용자가 요청하면 지연 시간이 가장 낮은 엣지 로케이션으로 요청이 라우팅되므로 가능한 최고의 성능으로 콘텐츠가 제공된다.
참고

CloudFront 배포 생성

CloudFront > 배포 > 배포 생성

원본 도메인에는 S3 정적 웹 호스팅 주소를 작성한다.

Redirect HTTP to HTTPS를 선택한다. 최종 사용자는 두 프로토콜 모두 사용할 수 있지만, HTTP 요청은 자동으로 HTTPS 요청으로 리디렉션된다.

대체 도메인 이름에 내 도메인을 작성하고 사용자 정의 SSL 인증서를 선택한다.

서브 도메인도 마찬가지로 동일하게 배포를 진행한다.

Route53 레코드 생성

Route53 > 호스팅 영역 > my-tcat.com > 레코드 생성

트래픽 라우팅 대상 - CloudFront 배포에 대한 별칙을 선택하고 자동완성되는 주소를 선택한다.

서브 도메인에 대한 레코드도 생성한다.

Route 53 > 호스팅 영역 에서 레코드를 확인할 수 있다.

배포 설정

Access Denied 방지

React에서는 react-router-dom을 이용해 라우팅을 하는데, 이 때문에 특정 route로 접속 했을 때 403, 404 에러가 발생한다.

CloudFront > 배포 > 오류페이지 > 사용자 정의 오류 응답 생성

403, 404 각각의 오류에 대해 응답 페이지 경로를 /index.html로 설정해준다.

Cache 문제, 파일 무효화 설정

CloudFront는 자동으로 24시간 동안의 캐시가 적용되어 배포가 적용되는 데 오랜 시간이 걸린다.

CloudFront > 배포 > 오류페이지 > 무효화 > 무효화 생성

객체 경로에 /*을 추가한다.

캐시 문제 때문에 매번 이렇게 배포마다 파일 무효화를 생성해 주어야 하는데, 이를 Github Actions에서 AWS CLI로 자동으로 수행하도록 할 수 있다.

Github Actions으로 배포 자동화

AWS IAM 사용자 추가

IAM이란 AWS 리소스에 대한 액세스를 안전하게 제어할 수 있는 웹 서비스이다. 여기서는 리소스(S3)에 접근할 수 있는 IAM 사용자를 추가할 것이다.

IAM > 액세스 관리 > 사용자 > 사용자 추가

사용자 이름을 작성하고, 액세스 키 - 프로그래밍 방식 액세스를 선택한다.

기존 정책 직접 연결을 선택하고 AmazonS3FullAccess와 CloudFrontFullAccess를 선택한다.

완료하고 .csv 다운로드받아 ID와 Access Key를 확인한다.

Github Secrets 설정

Github Repository > Settings > Actions secrets > New repository secret

ID와 Access Key, Cloudfront ID, .env에 작성된 것들을 secrets로 설정해준다.

Github Actions

Github Repository > Actions > set up a workflow yourself
main-deploy.yml 파일을 작성한다.

name: Deploy to Production
 
on:
  push:
    branches:
      - main
 
jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout source code
        uses: actions/checkout@master
 
      - name: Cache node modules
        uses: actions/cache@v1
        with:
          path: node_modules
          key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.OS }}-build-
            ${{ runner.OS }}-
 
      - name: Install Dependencies
        run: yarn install
 
      - name: Build
        env:
          CI: ''
          REACT_APP_SERVER: ${{ secrets.REACT_APP_SERVER }}
          REACT_APP_OCR_SERVER: ${{ secrets.REACT_APP_OCR_SERVER }}
          REACT_APP_OAUTH2_REDIRECT_URI: ${{ secrets.REACT_APP_OAUTH2_REDIRECT_URI }}
        run: yarn run build
        
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2
 
      - name: Upload to S3
        run: |
          aws s3 cp \
            --recursive \
            --region ap-northeast-2 \
            build s3://my-tcat.com
            
      - name: Invalidate files
        run: |
          aws cloudfront create-invalidation \
            --distribution-id ${{ secrets.AWS_DISTRIBUTION_ID }} \
            --paths "/*"

성공적으로 배포가 완료되었다.

백엔드는 소스파일을 S3에 올리고, CodeDeploy를 이용하여 EC2에 스프링 도커 컨테이너를 만들어 배포하고자 한다.

소스파일을 S3에 올리고, CodeDeploy를 이용하여 EC2에 스프링 도커 컨테이너를 만들어 배포하고자 한다.

과정
1. Github main 브랜치에 Push
2. Github Actions에서 AWS S3에 빌드 파일 및 Dockerfile, deploy.sh 등 업로드
3. Github Actions이 AWS CodeDeploy에 배포 요청
4. CodeDeploy가 배포 실행
5. 도커 빌드 및 실행

Github Actions으로 S3에 업로드

버킷 생성

소스코드를 저장할 버킷을 생성한다.

IAM 사용자 추가

IAM > 사용자 > 사용자 추가

사용자 이름 설정

사용자 이름은 github-action-s3-codedeploy으로 설정하였다.

정책 추가

github actions에서 AWS S3, CodeDeploy에 접근할 권한이 필요하다. AmazonS3FullAccessAWSCodeDeployFullAccess를 선택하여 추가한다.

완료하고 Access key ID와 Access Key를 확인한다.

Github Secrets 설정

  • APPLICATION: application.yml의 내용
  • AWS_ACCESS_KEY_ID: Access key ID
  • AWS_SECRET_ACCESS_KEY: Secret access key

Github Actions Workflow

Github Repository > Actions > set up a workflow yourself
main-deploy.yml 파일을 작성한다.

name: Deploy to Production

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source code
        uses: actions/checkout@master

      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'temurin'

      - name: Gradle Caching
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Make application.yml
        run: |
          cd ./src/main
          mkdir resources
          cd ./resources
          touch ./application.yml
          echo "${{ secrets.APPLICATION }}" > ./application.yml
        shell: bash
        
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build
        
      - name: Make zip file
        run: |
          mkdir deploy
          cp ./build/libs/*.jar ./deploy/
          zip -r -qq -j ./spring-build.zip ./deploy
          
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2
        
      - name: Upload to S3
        run: |
          aws s3 cp \
            --region ap-northeast-2 \
            ./spring-build.zip s3://tcat-spring
  • Make application.yml: Github Secrets의 저장된 secrets.APPLICATION으로 application.yml 파일을 만든다.

  • Make zip file: 압축을 위한 deploy 디렉토리를 만들어 .jar 파일을 복사한 후 spring-build.zip 파일을 만든다.

  • Upload to S3: tcat-spring 버킷에 zip파일을 업로드 한다.

버킷에 올라온 zip파일을 확인할 수 있다.

AWS CodeDeploy 설정

CodeDeploy는 Amazon EC2 인스턴스, 온프레미스 인스턴스, 서버리스 Lambda 함수 또는 Amazon ECS 서비스로 애플리케이션 배포를 자동화하는 배포 서비스이다.

배포하는 환경에 CodeDeploy Agent를 설치해야 하며, 배포 시 정의한 appspec.yml에 따라 동작하게 된다.

EC2 IAM Role 생성

EC2에서 CodeDeploy를 사용하기 위해 IAM Role을 생성한다. IAM Role은 주로 AWS 서비스들이 직접 다른 AWS 서비스를 제어하기 위해 사용한다.

IAM > 역할 > 역할 생성

AmazonEC2RoleforAWS-CodeDeploy 권한을 추가한다.

이름은 role-ec2-codedeploy로 지정하였다.

CodeDeploy IAM Role 생성

마찬가지로 CodeDeploy도 IAM Role을 생성한다.

사용사례에서 CodeDeploy를 선택한다.

권한이 자동으로 추가되어있다.

이름을 role-codedeploy로 지정하고 생성한다.

EC2 IAM 역할 수정

EC2 > 인스턴스 > 작업 > 보안 > IAM 역할 수정

IAM 역할에 role-ec2-codedeploy 지정하고 인스턴스를 재부팅한다.

EC2에 AWS CodeDeploy 에이전트 설치

CodeDeploy를 이용하려면 배포하는 환경에 CodeDeploy Agent를 설치해야한다.

# 설치
sudo yum -y update
sudo yum install -y ruby
aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2
chmod +x ./install
sudo ./install auto

# 확인
sudo service codedeploy-agent status

The AWS CodeDeploy agent is running as PID ~ 가 나오면 정상적으로 작동하는 것이다.

CodeDeploy 설정

애플리케이션 생성

CodeDeploy > 애플리케이션 > 애플리케이션 생성

애플리케이션 이름을 입력하고 컴퓨팅 플랫폼에 EC2를 선택하여 애플리케이션 생성을 완료한다.

배포 그룹 생성

CodeDeploy > 애플리케이션 > spring-deploy > 배포 그룹 > 배포 그룹 생성

배포 그룹 이름을 입력하고 서비스 역할에 만들어 둔 role-codedeploy를 지정한다.
배포 유형은 배포할 서비스가 1대이기 때문에 현재 위치를 선택한다.

환경 구성에 Amazon EC2 인스턴스를 선택하고 태그를 추가한다. 이 태그는 배포하려는 EC2 인스턴스의 태그와 동일하여야 한다.

배포 구성은 다음을 참고한다. 한번 배포할 때, 모든 인스턴스에 배포하도록 AllAtOnce를 선택한다.
로드 밸런싱 활성화는 해제한다.

EC2 설정

디렉토리 생성

mkdir ~/app

S3에 있는 소스를 내려받을 app 폴더를 생성한다.

도커 설치

# 도커 설치
sudo yum install docker -y
docker -v

# 도커 시작
sudo service docker start

# 확인
systemctl status docker.service

도커 실행을 위해 도커를 설치한다.

appspec.yml 작성

CodeDeploy에서 배포가 실행되면 이 appspec.yml파일에 따라 동작하게 된다.

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/app
    overwrite: yes

permissions:
  - object: /
    pattern: "**"
    owner: ec2-user
    group: ec2-user

hooks:
  ApplicationStart:
    - location: deploy.sh
      timeout: 60
      runas: ec2-user
  • files-destination: s3 zip 파일이 저장될 위치이다.
  • hooks-ApplicationStart: ApplicationStart단계에서 deploy.sh를 실행한다.

deploy.sh 작성

#!/bin/bash

echo "> 현재 실행 중인 Docker 컨테이너 pid 확인" >> /home/ec2-user/deploy.log
CURRENT_PID=$(sudo docker container ls -q)

if [ -z $CURRENT_PID ]
then
  echo "> 현재 구동중인 Docker 컨테이너가 없으므로 종료하지 않습니다." >> /home/ec2-user/deploy.log
else
  echo "> sudo docker stop $CURRENT_PID"   # 현재 구동중인 Docker 컨테이너가 있다면 모두 중지
  sudo docker stop $CURRENT_PID
  sleep 5
fi

cd /home/ec2-user/app
sudo docker build -t tcat-api-spring-boot-docker .
sudo docker run -d -p 8080:8080 tcat-api-spring-boot-docker

실행 중인 도커 컨테이너가 있다면 중지하고, 도커 이미지를 빌드하고 컨테이너를 실행하게 된다.

Dockerfile 작성

FROM openjdk:11

WORKDIR /tcat

COPY tcat-0.0.1-SNAPSHOT.jar app.jar

ENTRYPOINT ["java","-jar","app.jar"]

jar 파일을 실행하는 간단한 Dockerfile을 작성한다.

Github Actions Workflow에 CodeDeploy 설정 추가

main-deploy.yml에 CodeDeploy 설정을 추가한다.

name: Deploy to Production

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source code
        uses: actions/checkout@master

      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'temurin'

      - name: Gradle Caching
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-
      - name: Make application.yml
        run: |
          cd ./src/main
          mkdir resources
          cd ./resources
          touch ./application.yml
          echo "${{ secrets.APPLICATION }}" > ./application.yml
        shell: bash
        
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build
        
	  # 수정
      - name: Make zip file
        run: |
          mkdir deploy
          cp ./appspec.yml ./deploy/
          cp ./Dockerfile ./deploy/
          cp ./scripts/*.sh ./deploy/
          cp ./build/libs/*.jar ./deploy/
          zip -r -qq -j ./spring-build.zip ./deploy
          
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2
        
      - name: Upload to S3
        run: |
          aws s3 cp \
            --region ap-northeast-2 \
            ./spring-build.zip s3://tcat-spring
      
	  # 추가
      - name: Code Deploy
        run: aws deploy create-deployment --application-name spring-deploy
          --deployment-config-name CodeDeployDefault.OneAtATime
          --deployment-group-name spring-deploy-group
          --s3-location bucket=tcat-spring,bundleType=zip,key=spring-build.zip
  • Make zip file: appspec.yml, Dockerfile, scripts/deploy.sh을 zip 파일에 추가한다.
  • Code Deploy: CodeDeploy를 실행한다.

Application Load Balancer(ALB) 설정

서브 도메인 추가

Route5e > 호스팅 영역 > my-tcat.com > 레코드 생성

값에는 EC2의 IP 주소를 넣어두었다. ALB 설정을 마치면 변경할 것이다.

Certificate Manager SSL 인증서 발급

AWS Certificate Manager > 인증서 > 인증서 요청

인증서를 발급받고 'Route 53에서 레코드 생성' 버튼을 눌러 레코드를 생성한다.

로드 밸런서 생성

EC2 > 로드 밸런싱 > 로드 밸런서 생성

Application Load Balancer를 선택한다.

Network mapping에서는 가용영역을 선택한다.
Security groupts에서는 EC2와 같은 보안그룹을 선택해준다.

Create target group으로 타켓 그룹을 생성한다.

이름을 지정하고 프로토콜에 HTTP, Port에 80을 입력한다.

include as pending below를 누르고, Create target group으로 타겟 그룹 생성을 완료한다.

생성한 타겟그룹으로 forward 해주고 Create load balancer를 눌러 로드 밸런서 생성을 완료한다.

로드 밸런서 리스너 설정

로드 밸런서 > 리스너
HTTP 리스너의 규칙 편집을 선택하여 규칙을 편집한다.

HTTP 리스너 규칙 편집

규칙 THEN 부분에 리다렉션을 설정하고 HTTPS, 443 을 입력하고 업데이트를 완료한다.

HTTPS 리스너 추가


HTTPS, 443을 입력하고 forward to에 생성한 타겟 그룹을 지정한다.

생성한 SSL인증서를 지정하고 리스너 추가를 완료한다.

Route53 ALB 연결

Route5e > 호스팅 영역 > my-tcat.com > 레코드 > 레코드 편집

별칭을 선택하고 Application/Classic Load Balancer에 대한 별칭을 선택하고 등록한다

Nginx 설정

Nginx 설치

# 설치
sudo amazon-linux-extras install nginx1

# 동작
sudo service nginx start

EC2에 Nginx를 설치하고 동작시킨다.

프록시 설정 변경

sudo vim /etc/nginx/nginx.conf
server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        if ($http_x_forwarded_proto != 'https') {
                return 301 https://$host$request_uri;
        }

        location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header HOST $http_host;
                proxy_set_header X-NginX-Proxy true;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://127.0.0.1:8080;
                proxy_redirect off;
        }

}

server 부분을 위와 같이 변경한다.
80포트로 들어오면 8080으로 전달해주는 설정이다.

sudo service nginx restart

Nginx를 재시작하면 정상적으로 작동되는 것을 확인할 수 있다.

413 오류 해결

payload가 너무 큰 경우 nginx에서 오류가 발생하기도 한다.

http {
    client_max_body_size 50M;

    ...
}

다음을 추가하여 준다.

무중단 배포 설정

기존의 배포 방식은 도커 컨테이너를 중단하고 새로운 컨테이너를 만들어 실행하기까지 서비스 중단이 일어나게 된다. 유저가 서비스 중단을 느끼지 못하도록 Blue-Green 배포 방식을 사용하여 무중단 배포를 진행하려 한다.

Blue-Green 배포 방식

배포 전

배포 후

Blue-Green 배포 방식이란 기존 버전을 운영하면서 신규 버전을 준비하여 신규 버전으로 전환하고 기존 버전을 중단하는 방식이다.

Docker Compose 파일 작성

docker-compose.blue.yml

#blue
version: '3'
services:
  tcat-api:
    build: .
    ports:
      - "8081:8080"
    container_name: spring-blue

blue 컨테이너는 port가 8081번으로 설정된다.

docker-compose.green.yml

#green
version: '3'
services:
  tcat-api:
    build: .
    ports:
      - "8082:8080"
    container_name: spring-green

green 컨테이너는 port가 8082번으로 설정된다.

deploy.sh 수정

#!/bin/bash

cd /home/ec2-user/app

DOCKER_APP_NAME=spring

# 실행중인 blue가 있는지
EXIST_BLUE=$(docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml ps | grep running)

# green이 실행중이면 blue up
if [ -z "$EXIST_BLUE" ]; then
	echo "blue up"
	docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml up -d --build

	sleep 30

	docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml down
	docker image prune -af # 사용하지 않는 이미지 삭제

# blue가 실행중이면 green up
else
	echo "green up"
	docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml up -d --build

	sleep 30

	docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml down
	docker image prune -af
fi

Github Actions Workflow 수정

main-deploy.yml 수정

      - name: Make zip file
        run: |
          mkdir deploy
          cp ./docker-compose.blue.yml ./deploy/
          cp ./docker-compose.green.yml ./deploy/
          cp ./appspec.yml ./deploy/
          cp ./Dockerfile ./deploy/
          cp ./scripts/*.sh ./deploy/
          cp ./build/libs/*.jar ./deploy/
          zip -r -qq -j ./spring-build.zip ./deploy
  • docker-compose.blue.yml, docker-compose.green.yml 파일을 복사하는 과정을 추가한다.

Nginx 설정 변경

sudo vim /etc/nginx/nginx.conf
# 추가
upstream tcat-api-server {
        least_conn;
        server 127.0.0.1:8081 max_fails=3 fail_timeout=10s;
        server 127.0.0.1:8082 max_fails=3 fail_timeout=10s;
    }

server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        if ($http_x_forwarded_proto != 'https') {
                return 301 https://$host$request_uri;
        }

        location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header HOST $http_host;
                proxy_set_header X-NginX-Proxy true;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                # 수정
                proxy_pass http://tcat-api-server;
                proxy_redirect off;
        }
 }
  • proxy_pass: 요청이 오면 upstrem tcat-api-server로 전달한다.
  • max_fails: 3만큼 요청이 fail한 경우 다른 서버에게 요청이 넘어간다.
  • fail_timeout: 30동안 서버가 응답하지 않으면 fail로 생각한다.
sudo service nginx restart

Nginx를 재시작한다.

확인

배포를 할 때마다 다음과 같이 port가 변경된다. 또한, 배포 중에 웹사이트 새로고침을 계속 하여도 접속에 이상이 없음을 확인할 수 있다.

참고

https://velog.io/@younge/CloudFront-Route53으로-S3-HTTPS-정적-웹-호스팅하기
https://kimdohyeon.tistory.com/54
https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html
https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/welcome.html
https://loosie.tistory.com/424
https://loosie.tistory.com/425
https://galid1.tistory.com/745
https://devlog-wjdrbs96.tistory.com/291
https://medium.com/@vdongbin/aws-elb와-nginx로-https-서버-구축하기-736b8c5ee76
https://saksin.tistory.com/1388
https://webisfree.com/2018-03-29/nginx-413-request-entity-too-large-에러-해결하기-파일-업로드-사이즈
https://subicura.com/2016/06/07/zero-downtime-docker-deployment.html
https://velog.io/@jeff0720/Travis-CI-AWS-CodeDeploy-Docker-로-배포-자동화-및-무중단-배포-환경-구축하기-2

1개의 댓글

comment-user-thumbnail
2024년 3월 5일

흐름이 잘 보이는 좋은 글 정말 감사합니다.
백엔드 S3에서 EC2로 jar을 포함한 zip 파일을 넘겨주고, CodeDeploy를 이용하여 EC2에서 해당 jar를 도커 이미지로 빌드 및 실행하는 걸로 이해했습니다.
혹시 이 과정을, GitHub Actions workflow 단계에서 docker 이미지로 미리 만들어서 S3에 제공하는 것은 어떤 단점이 있나요? 제가 생각하는 단점은 S3 저장공간 사용량이 증가하는 것인데 그 이외에 어떤 단점이 있을지 생각이 안 납니다.
AWS가 Dockerfile에 대한 걸 모르게 하고, GitHub Actions에서 작업 환경에 대한 모든 버전 관리를 일임하고 싶어서 질문드립니다.

답글 달기