Skip to content

[INFRA] 프론트엔드 CI CD 구축

Leejin Yang edited this page Aug 15, 2023 · 1 revision

펀잇팀은 Jenkins를 통해 CI/CD를 구축했다. 그리고 AWS EC2를 사용해 배포한다.

아이템 설정과 AWS 접속 설정, Github Webhook 연동은 [INFRA 2] 백엔드 CI/CD 구축을 참고하길 바란다.


배포를 위한 Nginx 설치 및 설정

펀잇의 프론트엔드는 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에서 파이프라인을 구축하러 간다.


Jenkins 파이프라인 구축

AWS 접속 설정과 Github Webhook 연동이 된 상태에서 프론트엔드 파이프라인을 작성해본다. 새로운 Item에서 Pipeline을 선택해 생성한다.

그 전에 Jenkins에서는 NodeJS 빌드를 기본적으로 제공하고 있지 않기 때문에 NodeJS 플러그인을 먼저 설치해본다.


NodeJS 플러그인 설치

jenkins-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
                    '''
                }
            }
        }
    }
}

각 스테이지 별로 살펴보자.

1. Git Clone

stage('Git Clone') {
    steps {
        git branch: 'develop', url: {git url}
    }
}

Git에 올라가있는 프로젝트의 develop 브랜치를 clone한다.

2. FE-Build

stage('FE-build') {
    steps {
        dir("./frontend") {
            nodejs(nodeJSInstallationName: 'NodeJS 18.16.1') {
                sh 'yarn install && yarn build'
            }
        }
    }
}

clone한 프로젝트의 frontend디렉토리로 이동 후 NodeJs 설정, 패키지 install, 빌드를 진행한다.

3. Compression

stage('Compression') {
    steps {
        dir("./frontend") {
            sh '''
            rm -rf node_modules
            tar -cvf dist.tar dist
            '''
        }
    }
}

패키지 install을 통해 생성된 node_modules를 삭제한다. node_modules 삭제를 통해 인스턴스에서 차지하는 용량을 줄여주었다. 그리고 빌드된 파일이 있는 dist 디렉토리를 tar 파일로 압축한다.

4. Deploy

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 이슈

nginx를 통해 배포 후 사이트에 접속해보니 Permission denied 에러를 보여주면서 페이지가 정상적으로 로드되지 않았다.

이를 해결하기 위해 다시 배포 서버에 접속한다. 해결 방법을 먼저 말하면 nginx.conf에서 user를 변경해야한다.

# /etc/nginx/nginx.conf
user www-data
# ...

nginx.conf는 웹 서버의 모든 설정과 동작에 관련된 내용을 담고 있다. 동작할 때 이 설정에 따라 작동한다.

현재 nginx.conf에서 user의 default 값인 www-data로 되어있다.

nginx에서 root로 설정한 디렉토리 경로의 권한(유저 그룹)과 user를 일치시키면 해결할 수 있다.


이 글은 펀잇팀 황펭이 작성하였습니다.

🔐 공통

🔑 프론트엔드

🔒 백엔드

📝 회의록

🤩 데모데이

Clone this wiki locally