목차
1. CI/CD 개념
2. OverView
3. VPC 생성 및 연결
4. Github Actions 설정
5. AWS IAM 생성
6. AWS Elastic Beanstalk 설정
7. 프로젝트 파일 생성 및 수정
8. HTTPS 적용
https://aeeazip.tistory.com/51
[CI/CD] Github Actions + Elastic Beanstalk를 활용한 Node.js CI/CD 구축 (2)
목차 1. CI/CD 개념 2. OverView 3. VPC 생성 및 연결 4. Github Actions 설정 5. AWS IAM 생성 6. AWS Elastic Beanstalk 설정 7. 프로젝트 파일 생성 및 수정 8. HTTPS 적용 https://aeeazip.tistory.com/50 [CI/CD] Github Actions + Elastic
aeeazip.tistory.com
2편에서 5번 AWS IAM 생성부터 6번 AWS Elastic Beanstalk 설정까지 다뤘다. 전체적인 Overview가 궁금하다면 1편을 참고하길 바란다.
7. 프로젝트 파일 생성 및 수정
폴더 구조는 다음과 같다.
내 프로젝트 외에 배포를 위해 아래의 파일들을 새로 생성해주었다.
- ./platform\nginx\nginx.conf
- Procfile
- webpack.config.js
또한 아래의 파일을 수정해주었다.
- package.json
먼저 ./platform/nginx/nginx.conf 파일이다.
나는 nginx를 리버스 프록시 서버로 사용할 예정이기 때문에 nginx.conf 파일을 만들어 주었다.
/로 get 요청이 들어오면 http://node로 보내주고
http://node는 http://127.0.0.1:3000 즉 http://localhost:3000을 실행한다.
파일 내용은 아래와 같다.
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 {
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;
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;
}
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;
}
}
다음은 Procfile이다.
해당 파일 또한 새로 생성해주어야 한다.
https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/nodejs-configuration-procfile.html
Procfile을 사용하여 애플리케이션 프로세스 구성 - AWS Elastic Beanstalk
이 기능은 aws:elasticbeanstalk:container:nodejs 네임스페이스의 레거시 NodeCommand 옵션을 대체합니다.
docs.aws.amazon.com
일반적으로 Procfile을 사용하여 애플리케이션 프로세스를 구성하며 파일 안에 애플리케이션을 시작 하는 명령을 담고있다.
나는 아래와 같은 내용으로 파일을 만들어 주었다.
web: npm install & npm run start
다음은 Node.js 빌드를 위한 webpack 구성이다.
node.js 프로젝트에서 express를 사용하는 경우 하나하나 빌드해줘야해서 번거롭기 때문에 webpack을 사용했다.
webpack-node-externals의 경우 webpack의 번들링 과정에서 외부 모듈을 제외할 수 있도록 해주는 패키지이다.
프로젝트에서 작성했던 수많은 스크립트 파일들을 하나의 번들로 묶어주기 때문에 굉장히 편리하다.
먼저 webpack 관련 모듈의 설치가 필요하다.
npm install -D webpack webpack-cli webpack-node-externals
설치가 완료되었다면 package.json 하단에서 아래와 같은 내용을 확인할 수 있다.
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-node-externals": "^3.0.0"
다음으로 webpack.config.js 파일을 작성해주었다.
ES6가 아닌 CommonJS로 작성되어 있지만 실행 명령어가 webpack ~ 이기 때문에 ES6 문법으로 작성 시 바벨로 변환해주어야 하기 때문에 귀찮아진다..
const nodeExternals = require("webpack-node-externals");
const path = require("path");
module.exports = {
mode: "development",
context: __dirname + "/src",
entry: {
app: "../index.js",
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
exclude: /node_modules/,
},
],
},
target: "node",
externalsPresets: {
node: true,
},
externals: [nodeExternals()],
};
webpack.config.js를 작성했다면 package.json의 scripts 영역에 아래 명령어를 추가해주어야 한다.
"build": "webpack --mode production"
여기서 --mode production을 사용한 이유는 배포 모드가 번들링 과정에서 자체적으로 코드를 최적화해서 용량을 줄이기 때문이다. 위의 명령어 외에도 webpack이나 webpack --mode development를 사용해도 상관없다.
배포와 관련된 프로젝트 파일은 모두 작성해주었고 이제 ELB가 Health Check할 때 사용할 API만 작성해주면 된다!
다른 부분은 생략하고 오직 health check에 관련된 내용만 적어보자면
먼저 index.js에
import { healthRouter } from "./src/router/healthRouter.js";
app.use('/health', healthRoute);
app.get('/', (req, res, next) => {
res.send(response(status.SUCCESS, "루트 페이지!"));
})
// error handling
app.use((req, res, next) => {
const err = new BaseError(status.NOT_FOUND);
next(err);
});
healthRouter.js에
import express from "express";
import { healthCheck } from "../controller/healthController.js";
export const healthRouter = express.Router();
healthRouter.get("", healthCheck);
healthController.js에
import dotenv from "dotenv";
dotenv.config(); // .env 파일 사용 (환경 변수 관리)
export const healthCheck = (req, res, next) => {
res.send("HELLO, I'm Healthy! NODE_ENV = " + process.env.NODE_ENV);
};
다음과 같은 내용을 작성해주었다.
코드 전문을 참고하고 싶다면 아래 링크를 참고하길 바란다.
https://github.com/aeeazip/bloodtrail-be/tree/main
GitHub - aeeazip/bloodtrail-be: bloodtrail backend repository
bloodtrail backend repository. Contribute to aeeazip/bloodtrail-be development by creating an account on GitHub.
github.com
이제 기본적인 구성은 모두 마쳤기 때문에 깃허브 main 브랜치에 머지해주면 Github Actions이 동작하면서 ELB에 배포될 것이다! 실제로 배포에 성공한 경우 ELB 애플리케이션 환경에 OK 라고 뜨며 상태를 클릭했을 때 인스턴스 상태와 배포된 프로젝트 버전 등등을 확인할 수 있다.
도메인으로 접속했을 때 루트 페이지의 json 응답 결과도 확인할 수 있다.
8. HTTPS 적용
HTTPS 적용을 위해 먼저 도메인 구매가 필요하다. 나는 가비아에서 도메인을 구매해주었다.
웹을 넘어 클라우드로. 가비아
그룹웨어부터 멀티클라우드까지 하나의 클라우드 허브
www.gabia.com
이미 사용중인 도메인은 구매할 수 없으며, .site .com .shop .store 등등 도메인 확장자에 따라 가격이 천차만별이다.
(보통 .shop이나 .store 또는 .site가 가장 저렴한 축에 속한다)
나는 bloodtrail.site 라는 이름의 도메인을 구매해주었다.
그리고 구매한 도메인을 호스팅할 수 있도록 AWS에 등록해주었다.
먼저 AWS Route 53에서 호스팅 영역을 생성해주었다.
호스팅 영역 생성으로 만들어진 NS 레코드의 값 / 트래픽 라우팅 값(모자이크 된 부분)을 가비아 네임서버에 1 ~ 4차에 할당해준다.
다시 AWS Route 53으로 돌아가 레코드를 생성해준다.
루트 도메인에 대한 레코드를 생성하려면 레코드 이름을 따로 작성해주지 않아도 된다. 또한 트래픽 라우팅 대상을 Elastic Beanstalk 환경으로 지정하기 위해 검색 버튼을 눌러 ELB 환경을 선택해주어야한다.
이번엔 AWS Certificate Manager를 사용한 인증서 요청 단계이다.
인증서 유형으로 퍼블릭 인증서 요청을 선택하고
구매한 도메인 이름을 작성해준다.
인증서가 생성되었다면 도메인에서 Route 53에서 레코드 생성 버튼을 클릭해준다.
레코드 생성으로 만들어진 CNAME을 복사해 가비아에 등록해준다.
마지막으로 HTTPS 접속을 위해 ELB 애플리케이션 환경 리스너에 HTTPS 포트번호 443을 추가해주면 된다.
이때 반드시 위에서 발급받은 SSL 인증서를 선택해주어야 한다.
도메인 연결 과정은 아래 블로그에 자세한 설명이 나와있으니 참고하면 좋을 것 같다.
AWS Route53 으로 도메인(https) 연결하기
기존에 AWS ElasticBeanstalk으로 배포한 웹앱에 구입한 도메인을 연결할 필요가 있어 AWS Route53으로 도메인을 연결하였습니다. AWS Route53에서도 도메인 구매가 가능하나 제가 사용하려는 도메인이 AWS
omty.tistory.com
첫 node.js 프로젝트 + 첫 ELB 배포라 삽질의 연속이였지만 즐거웠다.
이 포스팅이 나처럼 첫 도전을 하고 있는 개발자에게 도움이 되기를 ♥
'Server > CI&CD' 카테고리의 다른 글
[CI/CD] Github Actions + Elastic Beanstalk를 활용한 Node.js CI/CD 구축 (2) (0) | 2024.03.11 |
---|---|
[CI/CD] Github Actions + Elastic Beanstalk를 활용한 Node.js CI/CD 구축 (1) (2) | 2024.02.18 |
[CI/CD] GitLab + Jenkins를 활용한 SpringBoot CI/CD 구축 (3) - 完 (2) | 2024.02.13 |
[CI/CD] GitLab + Jenkins를 활용한 SpringBoot CI/CD 구축 (2) (0) | 2023.10.20 |
[CI/CD] GitLab + Jenkins를 활용한 SpringBoot CI/CD 구축 (1) (0) | 2023.08.18 |