-
Notifications
You must be signed in to change notification settings - Fork 0
[INFRA] 프론트엔드 CI CD 구축
펀잇팀은 Jenkins를 통해 CI/CD를 구축했다. 그리고 AWS EC2를 사용해 배포한다.
아이템 설정과 AWS 접속 설정, Github Webhook 연동은 [INFRA 2] 백엔드 CI/CD 구축을 참고하길 바란다.
펀잇의 프론트엔드는 React 라이브러리를 사용해 구현했다. 펀잇의 클라이언트를 배포하기 위해 배포 서버에서 Nginx를 먼저 설치한다. 배포 서버에 접속해 아래의 코드를 차례로 실행한다.
1. Nginx 설치
sudo apt install nginx
2. 초기 설정 파일 삭제
sudo rm /etc/nginx/sites-available/default
sudo rm /etc/nginx/sites-enabled/default
3. 설정 파일 생성
sudo vi /etc/nginx/sites-available/project.conf
설정 파일에 아래 코드를 작성한다.
server {
listen 80;
location / {
root /home/ubuntu/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
-
listen
: nginx가 수신할 포트를 지정한다. HTTP 포트인 80으로 설정한다. -
location /
: 특정 요청에 대한 처리를 제공한다. URI 접두어가 /인 모든 요청은 아래 설정을 따른다. -
root
: 요청된 파일의 루트 디렉토리를 지정. React 빌드 시 번들 파일은 dist 디렉토리에 존재해 위와 같이 작성했다. -
index
: 해당 디렉토리의 기본 인덱스 파일 -
try_files
: 요청된 파일이 없는 경우 차례대로 시도할 파일이나 디렉토리를 지정한다.
펀잇은 클라이언트 사이드 라우팅을 사용한다. 하나의 html만 사용하기 때문에 응답으로 줄 리소스가 없을 수 있어 try_files을 추가했다.
4. /etc/nginx/sites-enabled 경로에 심볼릭 링크 생성
ln -s /etc/nginx/sites-available/project.conf /etc/nginx/sites-enabled/project.conf
웹 서버가 동작할 때 sites-enabled에 있는 설정 파일을 참조한다.
5. nginx 재실행
sudo systemctl restart nginx
# 기타 명령어
sudo systemctl stop nginx # nginx 중지
sudo systemctl start nginx # nginx 시작
sudo systemctl status nginx # nginx 동작 상태 확인
nginx를 설치하고 설정까지 했으니 이제 Jenkins에서 파이프라인을 구축하러 간다.
AWS 접속 설정과 Github Webhook 연동이 된 상태에서 프론트엔드 파이프라인을 작성해본다. 새로운 Item에서 Pipeline을 선택해 생성한다.
그 전에 Jenkins에서는 NodeJS 빌드를 기본적으로 제공하고 있지 않기 때문에 NodeJS 플러그인을 먼저 설치해본다.
Jenkins 관리 > Tools에서 NodeJS 버전과 전역으로 설치할 패키지를 설정할 수 있다. 펀잇은 NodeJS 버전 18.16.1, 그리고 yarn을 사용하고 있기 때문에 위와 같이 설정했다.
펀잇 프론트엔드 파이프라인은 다음과 같다.
pipeline {
agent any
stages {
stage('Git Clone') {
steps {
git branch: 'develop', url: {git url}
}
}
stage('FE-build') {
steps {
dir("./frontend") {
nodejs(nodeJSInstallationName: 'NodeJS 18.16.1') {
sh 'yarn install && yarn build'
}
}
}
}
stage('Compression') {
steps {
dir("./frontend") {
sh '''
rm -rf node_modules
tar -cvf dist.tar dist
'''
}
}
}
stage('Deploy') {
steps {
sshagent(credentials: ['aws-key']) {
sh '''
scp /var/jenkins_home/workspace/{item이름}/frontend/dist.tar ubuntu@${개발서버ip}:/home/ubuntu
ssh -t ubuntu@{개발서버ip} ./deploy-fe.sh
'''
}
}
}
}
}
각 스테이지 별로 살펴보자.
stage('Git Clone') {
steps {
git branch: 'develop', url: {git url}
}
}
Git에 올라가있는 프로젝트의 develop
브랜치를 clone한다.
stage('FE-build') {
steps {
dir("./frontend") {
nodejs(nodeJSInstallationName: 'NodeJS 18.16.1') {
sh 'yarn install && yarn build'
}
}
}
}
clone한 프로젝트의 frontend
디렉토리로 이동 후 NodeJs 설정, 패키지 install, 빌드를 진행한다.
stage('Compression') {
steps {
dir("./frontend") {
sh '''
rm -rf node_modules
tar -cvf dist.tar dist
'''
}
}
}
패키지 install을 통해 생성된 node_modules
를 삭제한다. node_modules 삭제를 통해 인스턴스에서 차지하는 용량을 줄여주었다. 그리고 빌드된 파일이 있는 dist
디렉토리를 tar 파일로 압축한다.
stage('Deploy') {
steps {
sshagent(credentials: ['aws-key']) {
sh '''
scp /var/jenkins_home/workspace/{item이름}/frontend/dist.tar ubuntu@${개발서버ip}:/home/ubuntu
ssh -t ubuntu@{개발서버ip} ./deploy-fe.sh
'''
}
}
}
Compression 단계에서 만든 dist.tar
파일을 scp
명령어를 통해 배포 서버로 전송한다. 그 후 배포서버의 deploy-fe.sh
스크립트를 실행해 배포 단계를 완료한다. 배포 서버에 아래와 같이 deploy-fe.sh 파일을 생성한다.
#!/bin/bash
tar -xvf dist.tar
rm -rf dist.tar
sudo service nginx restart
tar 파일 압축을 해제하고 삭제한 뒤 nginx를 재시작한다.
nginx를 통해 배포 후 사이트에 접속해보니 Permission denied
에러를 보여주면서 페이지가 정상적으로 로드되지 않았다.
이를 해결하기 위해 다시 배포 서버에 접속한다. 해결 방법을 먼저 말하면 nginx.conf
에서 user
를 변경해야한다.
# /etc/nginx/nginx.conf
user www-data
# ...
nginx.conf는 웹 서버의 모든 설정과 동작에 관련된 내용을 담고 있다. 동작할 때 이 설정에 따라 작동한다.
현재 nginx.conf에서 user의 default 값인 www-data
로 되어있다.
nginx에서 root로 설정한 디렉토리 경로의 권한(유저 그룹)과 user
를 일치시키면 해결할 수 있다.
이 글은 펀잇팀 황펭이 작성하였습니다.
- 📚 프론트엔드 개발 문서
- 🌏 브라우저 지원 범위
- 🧪 프론트엔드 테스트 전략
- [웹 접근성] a tag와 button의 차이는 무엇일까?
- multipart
- SvgSprite 컴포넌트 사용하기
- [INFRA] 프론트엔드 CI/CD 구축
- [기술 검토] 리액트 쿼리 도입 이유
- [기술] 로그인 기능 도입기
- 🐛 S3 배포 캐싱 오류
- 이미지를 위한 S3와 Cloudfront 설정하기
- 📓 성능리포트 ‐ 펀잇 서비스 최적화하기
- 펀잇 SEO 개선하기
- 📚 백엔드 개발 문서
- intellij에서 private DB 연결하기
- [INFRA 0] 전체 infra 구조 - ver1
- [INFRA 1] infra 서버 세팅
- [INFRA 2] 백엔드 CI/CD 구축
- [INFRA 3] 백엔드 DB 연결
- [INFRA 4] 깃허브 PR 라벨을 기준으로 젠킨스 빌드하기
- [LOG] 로그 세팅
- [Trouble Shooting] 일관된 테스트 격리 적용하기
- [Trouble Shooting] 프록시로 동작하는 @Transactional, 전파 옵션 관리