Infra/CICD

[Jenkins] React, github, CI/CD 구축 with. nginx

ckm7907 2024. 10. 23. 22:35

# 프론트 코드 자동 배포 구축

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을 날려보세요!