티스토리 뷰
정중한 지적은 언제나 환영합니다!
댓글로 편히 남겨주세요
지난 1편(AWS 세팅 관련)을 보고 오지 않으셨다면, 1편 먼저 정독 후 2편을 읽으시는 것을 추천드립니다.
https://rogersddt.tistory.com/24
AWS) Elastic beanstalk + Git Action 무 중단 배포 구현 - 1 (feat. S3)
정중한 지적은 언제나 환영합니다!댓글로 편히 남겨주세요오늘은 약 3일 간의 삽질(?)을 통해 얻은 내 경험과 이를 기반한 지식을 공유해보려 한다. 먼저 아래 서버, aws 스펙등을 공유 한다. vpc
rogersddt.tistory.com
2편은 프로젝트 설정 기반으로 설명드릴 예정입니다.
필자의 프로젝트인 node.js 런타임 환경 기반 express 서버로 설명 하겠습니다.
목차는 아래와 같습니다.
GitHub Secrets 설정
1. 시크릿 키 설정
2. AWS 정보 설정
프로젝트 설정
3. 구조 설명
4. deploy.yml
5. nginx.conf
6. Procfile
7. webpack
배포
8. S3 확인
9. EB 확인
10. 회고
1편에 이어 계속 진행해보겠습니다.
1. 시크릿 키 설정
사용자를 생성하여야 한다. AWS 서비스에서 생성하자.
IAM으로 이동 > 사용자 > 사용자 생성

권한 정책 선택 후 생성을 해줘야 한다.

정책 명은 AdministratorAccess-AWSElasticBeanstalk 이다. 선택 후 사용자 생성 버튼을 통해 생성 완료 해주자.

이어서 엑세스 키를 만들어준다.
생성된 사용자 선택 > 보안 자격 증명 > 액세스 키 만들기
반드시 키는 .csv 파일로 받자..! (아래에서 사용 예정)


이제 이 엑세스 키를 Github Secrets에 등록해 줄 것이다.
배포할 레포지토리 > Settings > Secrets and Variables > Actions 로 이동

초록색 New repostiory secret 버튼을 클릭 > 생성한 엑세스 키 정보 작성 후 저장
필자는
Access Key -> AWS_ACCESS_KEY_ID
Secret Key -> AWS_SECRET_ACCESS_KEY 로 저장했다


2. AWS 정보 설정
이어서 AWS 관련 정보도 저장 했다. 필자가 저장한 정보들은 아래와 같다.

AWS_ACCOUNT_ID : AWS 계정 ID
AWS_REGION : AWS 리전
EB_APP_NAME : AWS Elastic Beanstalk 애플리케이션 이름
EB_ENV_NAME : AWS Elastic Beanstalk 환경 이름
3. 구조 설명
필자의 프로젝트 구조는 아래와 같다. 주요 설정 파일들에 대해서 박스 처리를 해놨다.
하나씩 아래에서 만들어볼 것 이다.

4. deploy.yml
먼저 프로젝트 root 경로에 .github 폴더를 만들고 하위에 workflows 폴더를 만든다.
그 안에 deploy.yml을 작성해준다.

deploy.yml 파일을 아래와 같이 작성하였다. 언제까지나 참고 자료이고 본인의 배포 방식에 맞게 수정하면 된다.
파일을 보면 {{secrets.AWS_ACCESS_KEY_ID}} 같은 부분이 적혀있다.
이 부분은 이전에 깃허브에서 설정해주었던 이름과 같아야 한다.
name: Deploy to Amazon Web Service Elastic Beanstalk
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# 1. 코드 체크아웃
- name: Checkout code
uses: actions/checkout@v3
# 2. Node.js 환경 설정
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 22
# 3. 종속성 설치
- name: Install dependencies
run: npm ci
# 4. 애플리케이션 빌드
- name: Build application
run: npm run build
# 5. 필요한 파일 복사
- name: Prepare deployment package
run: |
cp -R .platform dist
cp package.json dist/package.json
cp package-lock.json dist/package-lock.json
cp Procfile dist/Procfile
# 6. 배포를 위한 app.zip 생성
- name: Zip application
run: |
cd dist
zip -r app.zip .
mv app.zip ../
# 7. S3에 업로드
- name: Upload to S3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
run: |
aws s3 cp app.zip s3://elasticbeanstalk-${{ secrets.AWS_REGION }}-${{secrets.AWS_ACCOUNT_ID}}/app.zip
# 8. Elastic Beanstalk에 배포
- name: Deploy to Elastic Beanstalk
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
EB_APP_NAME: ${{ secrets.EB_APP_NAME }}
EB_ENV_NAME: ${{ secrets.EB_ENV_NAME }}
run: |
aws elasticbeanstalk create-application-version \
--application-name "$EB_APP_NAME" \
--version-label "build-${{ github.run_number }}" \
--source-bundle S3Bucket="elasticbeanstalk-${{ secrets.AWS_REGION }}-${{secrets.AWS_ACCOUNT_ID}}",S3Key="app.zip"
aws elasticbeanstalk update-environment \
--application-name "$EB_APP_NAME" \
--environment-name "$EB_ENV_NAME" \
--version-label "build-${{ github.run_number }}"
# 9. 디버그용 로그 확인 (옵션)
- name: Debug logs
env:
EB_ENV_NAME: ${{ secrets.EB_ENV_NAME }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
if: failure()
run: |
echo "Fetching Elastic Beanstalk logs..."
aws elasticbeanstalk request-environment-info \
--environment-name "$EB_ENV_NAME" \
--info-type tail
aws elasticbeanstalk retrieve-environment-info \
--environment-name "$EB_ENV_NAME" \
--info-type tail
5. nginx.conf
프로젝트 root 경로에 .platform 폴더를 만들고 그 하위에 nginx 폴더를 만든다.
그리고 그 안에 nginx.conf를 작성한다.
user nginx;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 33282;
events {
use epoll;
worker_connections 1024;
multi_accept on;
}
http {
types_hash_max_size 2048;
types_hash_bucket_size 128;
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
include conf.d/*.conf;
map $http_upgrade $connection_upgrade {
default "upgrade";
}
upstream node {
server 127.0.0.1:3000;
keepalive 1024;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
client_body_buffer_size 50m;
location / {
proxy_pass http://node;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Added buffer related settings
proxy_buffers 32 128k;
proxy_buffer_size 256k;
# Set appropriate timeout values
proxy_read_timeout 30s;
proxy_send_timeout 30s;
}
access_log /var/log/nginx/access.log main;
gzip off;
gzip_comp_level 4;
# Include the Elastic Beanstalk generated locations
include conf.d/elasticbeanstalk/healthd.conf;
}
}
6. Procfile
프로젝트 root 경로에 Procfile을 추가한다.

파일안에 아래 내용을 작성한다.
7. webpack
프로젝트 root 경로에 webpack.config.js를 추가해준다.
본 프로젝트는 ES 모듈이 아닌 CommonJS를 사용하였다. 이 점 참고 바란다.

파일 안에 아래 내용을 작성한다.
const nodeExternals = require("webpack-node-externals");
const path = require("path");
module.exports = {
mode: "deveplopment",
entry: {
app: './app.js', // 프로젝트 구동 파일
},
output: {
path: path.resolve('./dist'),
filename: "main.cjs",
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
exclude: /node_modules/,
},
],
},
target: "node",
externalsPresets: {
node: true,
},
externals: [nodeExternals()],
};
이어 webpack 관련 모듈을 설치한다.
npm install -D webpack webpack-cli webpack-node-externals
package.json에 설정을 추가한다.
"main": "./dist/main.cjs",
"scripts": {
"build": "webpack --mode production",
"start:dist": "node main.cjs",
"start": "node main.cjs"
},
// 등등 ...
8. S3 확인
이제 배포 준비가 끝났다. 이제 테스트를 해볼 시간이다.
기존의 EB환경에 있는 도메인을 따라 들어가본다.


배포 전 Hello, Express! 문구가 보인다. Git -> S3 -> EB를 거쳐 무중단 배포를 시도해볼 것 이다.
App.js 파일에서 해당 문구를 수정해서 배포해보자.


이제, S3에 압축 zip 파일이 올라갔는지 확인한다.

9. EB 확인
S3까지는 잘 올라간 것이 확인 되었다. 이제 S3에서 EB로 배포가 잘 이루어지는 지 확인하자.

최종적으로 롤링 배포를 통해 무 중단 배포가 이루어 졌음을 로그를 통해 확인 하였다. 롤링 배포에 대한 이해가 필요 하다면 아래 링크를 첨부한다.
https://itwiki.kr/w/%EB%A1%A4%EB%A7%81


10. 회고
이로서 Git Actions + S3 + EB를 활용하여 무 중단 배포를 구현해 보았다.
사실 이전에 CodeDeploy 서비스를 사용하여 블루 그린 배포를 구현해 보았어서 EB 또한 같은 결?의 서비스 인지 알고 CodeDeploy처럼 사전 설정을 해 주었다.
그 중 하나가 1편에서 보인 AMI를 기존 EC2 이미지를 사용하여 환경을 생성한 것이다.
CodeDeploy에 비해 EB의 장점은 간단하고 빠르게 배포를 자동으로 해주는 것이다.
즉, 기존의 CodeDeploy에서 해주던 설정들을 따로 해주지 않아도 되는 것이었다. 에이전트 설치, systemd 설정 등 자동화 배포에 필요한 패키지 설치나 인스턴스 생성 후 프로세스 작업 등의 설정은 알아서 EB에서 해준다. 따라서 AMI, 혹은 기타 설정 등을 따로 해주지 않아도 되고 EB에서 제공하는 것을 사용해도 무방하다. (필자는 agent 설치, systemd 다 설정해주고 해도 헬스체크가 되지 않았다. 이 것 가지고 3일을 고생했다.)
물론 커스텀 AMI나 관련 설정을 하고 EB 환경을 생성해도 되지만, 내가 모르는 구동에 필요한 설정들이 많을 것이고, 이 것들을 전부 세팅해주지 않는 한 에러가 발생할 것이다. 또한 이는 EB를 사용하는 취지와도 다르기에 필자와는 다르게
항상 어떠한 서비스를 사용하기 전 서비스의 개요, 특징, 기능 등을 확인한 후 이에 맞게 사용하기를 바란다.
이상 !
*다음편은 S3 -> ECR을 이용한 롤링 배포를 보여드릴게요*
'AWS' 카테고리의 다른 글
EC2에 Github Action, AWS ECR 사용하여 node.js 프로젝트 배포해보기 (0) | 2024.12.16 |
---|---|
Elastic beanstalk + Git Action 무 중단 배포 구현(완) - 3 (feat. ECR) (0) | 2024.12.16 |
Elastic beanstalk + Git Action 무 중단 배포 구현 - 1 (feat. S3) (2) | 2024.12.05 |
EC2 모니터링- Slack 슬랙 연동 하여 알림 받기 (0) | 2024.08.24 |
- Total
- Today
- Yesterday
- 자료구조
- 프로그래머스
- k8s
- 백준 상자 넣기 자바
- dfs
- docker
- k8s object
- StatefulSet
- 구간합구하기
- 쿠버네티스 개념
- 단지번호붙이기 자바
- 무중단배포
- Java #객체 #자바기초 #자바
- Java #코린이 #자바
- 백준 1965 풀이
- 자바
- java #스프링 #spring #server
- EC2
- java
- 마법사 상어와 비바라기 자바
- 쿠버네티스 오브젝트
- EB
- 단지번호붙이기 JAVA
- ECR
- AWS
- 행렬 테두리 회전하기 자바
- 백준 그림 자바
- 백준 상자넣기
- 코딩테스트
- 백준
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |