forked from boostcampwm-2024/web17-juchumjuchum
-
Notifications
You must be signed in to change notification settings - Fork 1
Github Actions를 이용한 CI CD 구축
김두종 edited this page Jan 15, 2025
·
3 revisions
![](https://private-user-images.githubusercontent.com/49023732/402978976-f1e30be7-0f06-4741-a605-bb9fe2ebc8d3.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1MDg2MTUsIm5iZiI6MTczOTUwODMxNSwicGF0aCI6Ii80OTAyMzczMi80MDI5Nzg5NzYtZjFlMzBiZTctMGYwNi00NzQxLWE2MDUtYmI5ZmUyZWJjOGQzLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDA0NDUxNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWIwOGMyMjNjMWM2YjIxZWU1YzNlMWE0YjRiNTI4MGFiZDEyYTlhNWEwOTQ3MWQ1YTZhNDdiNjkyNDNkMzVlZWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.OjJbjAz95s2Ix6ZyDa09gv9J31kG06us5FMEKoR9CFY)
![](https://private-user-images.githubusercontent.com/49023732/402978449-7b999a37-f9e5-4e2f-8767-e7c7bfcb45d0.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1MDg2MTUsIm5iZiI6MTczOTUwODMxNSwicGF0aCI6Ii80OTAyMzczMi80MDI5Nzg0NDktN2I5OTlhMzctZjllNS00ZTJmLTg3NjctZTdjN2JmY2I0NWQwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDA0NDUxNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTA4ZWE3OGU1OTAzMGE3ZTJhYWE3ZTZjYjllODI5ZGUwMTU2OWRkYjEwOTcwYjgzNzZmZDU0YmVjZDkwMGI1ZGEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.cbfsfr1aHNwlT2UpYM-Vx1GNx5Gr2PzYXl-AQv8iUVc)
- github actions를 이용한 CI/CD의 기본 구조는 github의 workflow를 활용하는 것
- workflow 파일을 작성하기 위해 github workflow의 기본 개념부터 학습. 학습 정리
- 순서
- github actions 활성화
- workflow YAML 파일 작성
- CI/CD가 이루어질 이벤트를 등록
- ex) dev 브랜치가 변경될 때
- CI/CD가 이루어질 이벤트를 등록
- github repository의 settings에서 필요한 secrets 등록
- 이후 이벤트가 trigger 될 때마다 작성한 workflow가 실행된다
- dev 브랜치에 push 이벤트가 발생하면
- github에서 ubuntu 서버를 실행시키고
- docker in docker 컨테이너를 설치
- 소스코드를 가져오고, yarn 설정 캐싱
- 패키지 의존성을 설치하고, 백엔드와 프론트엔드 코드 빌드
- Dokcer hub에 로그인하고, Dockefile들을 기반으로 백엔드와 프론트엔드 docker image 빌드 및 푸시
- NCP 서버 인스턴스에 접속 및 docker compose 실행
[.github/deploy-dev.yml]
name: Deploy Dev in Monorepo
on:
push:
branches:
- dev
jobs:
build-and-deploy:
runs-on: ubuntu-latest
services:
docker:
image: docker:20.10.7
options: --privileged
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Cache Yarn dependencies
uses: actions/cache@v3
with:
path: |
**/node_modules
~/.yarn-cache
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build backend and frontend
run: |
yarn workspace backend build
yarn workspace frontend build
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker images
run: |
# 백엔드 이미지 빌드 및 푸시
docker build -t ${{ secrets.DOCKER_USERNAME }}/backend:latest -f packages/backend/Dockerfile .
docker push ${{ secrets.DOCKER_USERNAME }}/backend:latest
# 프론트엔드 이미지 빌드 및 푸시
docker build -t ${{ secrets.DOCKER_USERNAME }}/frontend:latest -f packages/frontend/Dockerfile .
docker push ${{ secrets.DOCKER_USERNAME }}/frontend:latest
- name: Deploy to server
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY}}
password: ${{ secrets.SERVER_PASSWORD }}
port: ${{ secrets.SERVER_PORT }}
script: |
docker pull ${{ secrets.DOCKER_USERNAME }}/frontend:latest
docker pull ${{ secrets.DOCKER_USERNAME }}/backend:latest
docker compose down
docker compose up -d
-
DOCKER_USERNAME
: 도커 허브 아이디 -
DOCKER_PASSWORD
: 도커 허브 비밀번호 -
SERVER_HOST
: 서버 인스턴스 공용 IP -
SERVER_USER
: 서버 접속시 유저 정보 -
SERVER_SSH_KEY
:.pem
키 파일 -
SERVER_PASSWORD
: 네이버 클라우드 플랫폼 기준 서버 인스턴스의 관리자 비밀번호 -
SERVER_PORT
: 22(디폴트값)
- Docker
- 도커만 설치한다면 서버의 환경과 관계없이 우리가 설정한 대로 프론트, 백엔드, nginx 서버를 띄울 수 있다.
- /root
- docker-compose.yml
- /nginx
- reverse-proxy.conf
- nginx-frontend.conf
- /configs
- /frontend
- .env
- /backend
- .env
- /frontend
[docker-compose.yml]
networks:
corp:
driver: bridge
services:
nginx_proxy:
image: nginx:1.27.2-alpine
container_name: nginx_proxy
ports:
- '80:80'
depends_on: #proxy가 먼저 켜지는 경우 죽어버리는 문제가 있었음. 의존성 추가
- frontend
- backend
volumes:
- ./nginx/reverse-proxy.conf:/etc/nginx/nginx.conf
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
networks:
- corp
frontend:
image: frontend:latest
container_name: frontend
env_file:
- ./configs/frontend/.env
environment:
- NODE_ENV=production
depends_on:
- backend
volumes:
- ./nginx/nginx-frontend.conf:/etc/nginx/nginx.conf
networks:
- corp
backend:
image: backend:latest
container_name: backend
env_file:
- ./configs/backend/.env
environment:
- NODE_ENV=production
networks:
- corp
[/nginx/reverse-proxy.conf]
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 백엔드 upstream 설정
upstream nest-api-server {
server backend:3000;
}
# 프론트엔드 upstream 설정
upstream static-server {
server frontend:8080;
}
server {
listen 80;
server_name juchumjuchum.site;
location / {
proxy_pass http://static-server/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /api {
proxy_pass http://nest-api-server/api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
#include /etc/nginx/conf.d/*.conf;
}
[/nginx/nginx-frontend.conf]
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 백엔드 upstream 설정
upstream nest-api-server {
server backend:3000;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 8080;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
# 웹 소캣 경로 추가
location /socket.io {
proxy_pass http://nest-api-server/socket.io;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
}
location / {
try_files $uri $uri/ /index.html;
}
}
}
- deploy-dev.yml 파일에 SERVER_PASSWORD 와 관련된 설정을 명시하지 않았기 때문에 발생
- 해결방법
- NCP의 경우 서버 인스턴스의 관리자 비밀번호를 추가
- 기존에 사용하던 docker-compose 명령어가 Compose V1에 해당하는데, 현재 서버 인스턴스에는 Compose V2가 설치되어 있기 때문에 발생
- 해결방법
- docker-compose 대신 docker compose 사용
- [1주 2일차 합동 개발 일지](marketCap 데이터 null 이슈 해결)
- 인터셉터를 이용한 로거 개발기
- 배포 환경에서 웹 소캣 연결 실패 문제 해결
- Github Actions를 이용한 CI CD 구축
- nGrinder 테스트 시나리오
- nGrinder TPS가 측정되지 않는 문제
- 메트릭 수집에 필요한 툴들 설치하기
- Node Exporter 연결 안되는 문제
- StockService에서 Repository 계층 분리하기
- Server와 Grafana연동하기
- Guest 로그인 중복 문제 해결
- 뉴스요약 AI 프롬프팅
- 주식 학습 도우미 AI 프롬프팅
- 뉴스 요약 클로바 API 연동하기
- 샘플 뉴스 데이터를 활용한 Clova 요약 성능 확인
- 공동 개발 일지 - 뉴스 요약 AI 기능 도입 시도
- [AI 뉴스 요약]네이버 뉴스 크롤링 기능을 구현해보자
- AI 요약결과 db 저장
- 크롤링시 뉴스 카테고리 필터링 기능 추가하기
- 클로바 API 응답 형식 오류 해결
- 클로바 API 응답 형식 검증하기
- 주식 상세 페이지 차트 버그 해결하기
- NewsSummaryService를 위한 커스텀 에러 구현
- 실시간 주식 데이터 스로틀링 구현
- AI 기반 주식 뉴스 처리 시스템의 안정성 개선