[Jenkins] React, github, CI/CD 구축 with. nginx
# 프론트 코드 자동 배포 구축
github에 커밋을 할 때마다 자동으로 서버에 배포되도록 설정하려고 한다.
먼저 jenkins가 설치되어야 한다. 이 부분은 나중에 따로 블로깅하도록 하겠다.
# Github 설정
## docker 파일 추가
react 폴더 아래(src폴더와 같은 위치에)에 dockerfile을 추가한다.
eblog-reader
└─src
└─public
└─Dockerfile
# base image 설정(as build 로 완료된 파일을 밑에서 사용할 수 있다.)
FROM node:22-alpine as build
# 컨테이너 내부 작업 디렉토리 설정
WORKDIR /app
# app dependencies
# 컨테이너 내부로 package.json 파일들을 복사
COPY package*.json ./
# package.json 및 package-lock.json 파일에 명시된 의존성 패키지들을 설치
RUN npm install
# 호스트 머신의 현재 디렉토리 파일들을 컨테이너 내부로 전부 복사
COPY . .
# npm build (메모리 제한을 늘려서 실행)
RUN NODE_OPTIONS="--max-old-space-size=4096" npm run build
# prod environment
FROM nginx:stable-alpine
# root 사용자로 전환
USER root
# 이전 빌드 단계에서 빌드한 결과물을 /usr/share/nginx/html 으로 복사한다.
COPY --from=build /app/build /usr/share/nginx/html
# 기본 nginx 설정 파일을 삭제한다. (custom 설정과 충돌 방지)
RUN rm /etc/nginx/conf.d/default.conf
# custom 설정파일을 컨테이너 내부로 복사한다.
COPY nginx/nginx.conf /etc/nginx/conf.d
# /docker-entrypoint.sh 파일에 실행 권한 부여
RUN chmod +x /docker-entrypoint.sh
# 컨테이너의 80번 포트를 열어준다.
EXPOSE 80
# nginx 서버를 실행하고 백그라운드로 동작하도록 한다.
CMD ["nginx", "-g", "daemon off;"]
## nginx 파일 추가
react 폴더 아래에 nginx 폴더를 만들고, nginx 를 추가한다
eblog-reader
└─src
└─public
└─Dockerfile
└─nginx
└─nginx.conf
# front/nginx/nginx.conf
server {
listen 80;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
# root를 /usr/share/nginx/html 을 바라보게 했으므로(Dockerfile 참고)
# 해당 경로 아래에 배포해주면 됨
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
## access token 발급
프로필 사진 클릭 > setting 클릭 > developer setting 클릭 > Personal acess tokens > Tokens
여기서 Generate new token을 클릭하고
Select scope 체크부분에서 repo, admin:org, admin:repo_hook를 체크하여 아래 Generate token 버튼을 눌러준다.
생성된 토큰을 메모장에 저장한다.
## webhook 연결
Add webhook을 추가하고, jenkins의 webhook을 추가하는데, url 을 jenkins주소에서 /github-webhook/을 추가한다.
# jenkins 설정
## Github 토큰 설정
Username에 GITHUB ID(아무거나 써도 상관 x), Password에 위에서 생성된 토큰 정보를 모두 복붙한다.
ID는 pipeline에서 쉽게 알아볼 수 있도록 github-token으로 설정한다.
## .env 파일 설정(없으면 생략)
secret file로 설정하고, file에 react 의 .env 파일을 추가하고 ID는 pipeline에 입력할 걸로 설정한다.
## plugin 설치
### NodeJS
Available plugins 에서 NodeJS를 찾아서 설치하면 된다.
### stage view plugin
pipeline 진행 상황을 볼 수 있는 시각화 플러그인이다.
### Github Integration Plugin
Github에서 설정한 webhook을 연결하기 위해 설정한다.
## node.js 설치
npm 명령어를 사용해서 패키지를 다운받기 위해서 node.js가 필요하다.
jenkins 관리에서 Tools에 아래로 내리면 nodeJS가 있다. 각 프로젝트 버전에 맞게 설치하면 된다.
## pipeline 구축
위 메뉴대로 새로운 아이템을 구축하는데, 이 때 아이템 타입을 pipeline으로 설정할 것이다.
오해냐하면 각각의 블럭을 나누어 유지보수와 코드를 읽기 편하고, pipeline stage view 플러그인을 통해 빌드를 시각적으로 확인할 수 있는 장점이 있기 때문이다.
## pipeline 설정
### GitHub project
먼저 GitHub project에 github url을 입력한다.
### Build Trigger 설정
GitHub hook trigger을 체크해서 GitHub에서 받은 Webhook 이벤트를 기반으로 변경 사항을 감지해 빌드를 시작한다.
## pipeline 구축
pipeline {
agent any
environment {
repositoryReact = 'eblog-react'
REACT_ENV = credentials('eblog-react-env')
}
tools {
nodejs("node22")
}
stages {
stage('Git Pull') {
steps {
git branch: 'main', credentialsId: 'github-token', url: 'https://github.com/eBlogReader/eBlogReader-FE.git/'
}
}
stage('Inject .env File') {
steps {
dir('eblog-reader') {
script {
// Copy the secret file content to .env
withCredentials([file(credentialsId: 'eblog-react-env', variable: 'SECRET_ENV')]) {
sh 'cp $SECRET_ENV .env'
}
// Check if the .env file was created successfully
sh 'ls -la .env'
}
}
}
}
stage('SSAFY React Deploy') {
steps {
dir('eblog-reader') {
script {
// Build Docker image with a tag using the build number
sh "docker build -t ${env.repositoryReact}:${env.BUILD_NUMBER} ."
// Stop and remove the existing container if it exists
sh 'docker ps -q -f name=react-container | xargs --no-run-if-empty docker stop'
sh 'docker ps -a -q -f name=react-container | xargs --no-run-if-empty docker rm'
// Run the new Docker container
sh "docker run -d -p 3002:80 --name react-container --network jenkins_db-network ${env.repositoryReact}:${env.BUILD_NUMBER}"
// Remove old Docker images except for the current one
sh "docker image prune -f --filter until=24h"
}
}
}
}
}
}
## 아이템 메인 화면에 이렇게 뜨면 성공!! (pipeline stage view)
참고로 jenkins가 github webhook을 받지 않는다면 한번 빌드하고 webhook을 날려보세요!