티스토리 뷰

728x90
반응형

서론

최근 많아지는 SPA 개발 요구사항에 따라 마찬가지로 SPA 배포 환경을 구성해야 하는 경우도 종종 생겨나고 있다. 이번 포스팅에서는 SPA Application을 배포하기 위한 CI 서버 환경 구성 방법에 대해 알아보도록 한다.


본문

SPA의 대표적인 JavaScript 언어로는 Vue, Angular, React가 있다. 셋 모두 NodeJS 기반 모듈로써 Node 빌드 & 배포 방식을 사용하고 있다.

1) Node & NPM 설치

따라서 Jenkins 서버에 SPA Application을 빌드/배포하기 위한 node & npm 이 설치되어 있어야 한다.

[root@ciserver node]# wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
=> Downloading nvm from git to '/root/.nvm'
=> Cloning into '/root/.nvm'...
remote: Enumerating objects: 267, done.
remote: Counting objects: 100% (267/267), done.
remote: Compressing objects: 100% (239/239), done.
remote: Total 267 (delta 30), reused 88 (delta 18), pack-reused 0
Receiving objects: 100% (267/267), 119.57 KiB | 0 bytes/s, done.
Resolving deltas: 100% (30/30), done.
=> Compressing and cleaning up git repository

=> Appending nvm source string to /root/.bashrc
=> Appending bash_completion source string to /root/.bashrc
=> Close and reopen your terminal to start using nvm or run the following to use it now:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
[root@ciserver node]# source ~/.bash_profile
[root@ciserver node]# nvm install v14.15.1
Downloading and installing node v14.15.1...
Downloading https://nodejs.org/dist/v14.15.1/node-v14.15.1-linux-x64.tar.xz...
######################################################################## 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v14.15.1 (npm v6.14.8)
Creating default alias: default -> v14.15.1 *
[root@ciserver node]# source ~/.bash_profile
[root@ciserver node]# 

위와 같이 node를 설치하면 자동으로 npm은 함께 설치된다. node 관련 자세한 설명은 아래 포스팅을 참조한다.

[④ 개발, 데이터베이스/ⓝ NodeJS] - [Node.JS] VSCode 개발환경 구성하기

[④ 개발, 데이터베이스/ⓝ NodeJS] - [Node.JS] 기동 및 모니터링

[④ 개발, 데이터베이스/ⓝ NodeJS] - [Node.JS] NPM (Node Package Manager)

[root@ciserver node]# node -v
v14.15.1
[root@ciserver node]# npm -v
6.14.8
[root@ciserver node]#

설치가 완료되면, 위와 같이 버전을 확인한다. 중요한건 개발환경에서 사용하던 Node 버전과 동일한 버전을 서버 컴파일 버전으로 사용해야 Node 모듈 버전 차이로 인한 문제가 발생하지 않는다.

2) npm install & npm run build

[root@ciserver SPA_Deploy_Job]# ls -la
total 16
drwxr-xr-x. 5 root root 121 Nov 29 11:43 .
drwxrwxrwx. 8 root root 126 Nov 29 11:19 ..
drwxr-xr-x. 8 root root 162 Nov 29 11:40 .git
-rw-r--r--. 1 root root 230 Nov 29 11:25 .gitignore
-rw-r--r--. 1 root root 315 Nov 29 11:25 README.md
-rw-r--r--. 1 root root  73 Nov 29 11:25 babel.config.js
-rw-r--r--. 1 root root 927 Nov 29 11:25 package.json
drwxr-xr-x. 2 root root  43 Nov 29 11:25 public
drwxr-xr-x. 8 root root 160 Nov 29 11:25 src
[root@ciserver SPA_Deploy_Job]# 

예를 들어 GitHub와 연동하여 다운로드 받은 디렉토리는 위와 같다고 가정하자. npm 모듈이 설치가 완료되면 Jenkins에서 적용하기 위해 Jenkins를 재기동한다.

[root@ciserver SPA_Deploy_Job]# ls -la
total 492
drwxr-xr-x.   6 root root    166 Nov 29 11:44 .
drwxrwxrwx.   8 root root    126 Nov 29 11:19 ..
drwxr-xr-x.   8 root root    162 Nov 29 11:43 .git
-rw-r--r--.   1 root root    230 Nov 29 11:25 .gitignore
-rw-r--r--.   1 root root    315 Nov 29 11:25 README.md
-rw-r--r--.   1 root root     73 Nov 29 11:25 babel.config.js
drwxr-xr-x. 810 root root  24576 Nov 29 11:44 node_modules
-rw-r--r--.   1 root root 445708 Nov 29 11:43 package-lock.json
-rw-r--r--.   1 root root    927 Nov 29 11:25 package.json
drwxr-xr-x.   2 root root     43 Nov 29 11:25 public
drwxr-xr-x.   8 root root    160 Nov 29 11:25 src
[root@ciserver SPA_Deploy_Job]# 

npm install이 정상적으로 완료되면, node module이 설치되며 package-lock.json 파일과 mode_modules 디렉토리가 생성된다.

npm run build가 완료되면 dist 디렉토리에 배포하기 위한 파일들이 생성된다.

3) Jenkins Job 생성

pipeline {
    agent any
    parameters {
        string(name: 'GIT_URL', defaultValue: 'https://github.com/sonnaraon/VueJS.git', description: 'GIT_URL')
        booleanParam(name: 'VERBOSE', defaultValue: false, description: '')
    }
    
    environment {
        GIT_BUSINESS_CD = 'master'
        GIT_CREDENTIAL_ID = 'superuser'
        VERBOSE_FLAG = '-q'
    }
    
    stages{
        stage('Preparation'){
            steps{
                script{
                    env.ymd = sh (returnStdout: true, script: ''' echo `date '+%Y%m%d-%H%M%S'` ''')
                }
                echo("params : ${env.ymd} " + params.tag)
            }
        }
        
        stage('Checkout'){
            steps{
                git(branch: "${env.GIT_BUSINESS_CD}",
                credentialsId: "${env.GIT_CREDENTIAL_ID}", url: params.GIT_URL, changelog: false, poll: false)
            }
        }
        
        stage('Build and Deploy'){
            steps{
                sh "rm -rf package-lock.json node_modules"
                sh "npm install"
                sh "npm run build"
                sh "cp -rf dist/* /var/www/html/"
            }
        }
    }
}

- Jenkins Pipeline Stage로 Preparation > Checkout > Build and Deploy Job을 순서대로 실행한다.

Build and Deploy Stage에 포함되어 있는 npm install & npm run build를 통해 배포하기 위한 dist를 생성할 수 있으며, 이를 배포하기 위한 형태로 전송하거나 생성한다.

현재는 같은 서버에 설치되어 있는 apache에서 Vue를 서비스하기 위해 /var/www/html 디렉토리로 dist 디렉토리의 파일들을 복사하는 형태로 구성하였으며, Remote 서버에 전송하기 위해서는 ssh로 전송하거나, Docker File로 생성하기 위한 과정 등이 추가로 발생할 수 있다. 이는 아래 포스팅을 통해 참고한다.

[④ 개발, 데이터베이스/ⓒ CI CD] - Kubernetes Jenkins - 자동 배포환경 구성 (1/2)

[④ 개발, 데이터베이스/ⓒ CI CD] - Kubernetes Jenkins - 자동 배포환경 구성 (2/2)

마지막으로 배포 된 화면을 확인해 보자.

위와 같이 배포된 index.html을 기반으로 초기 화면을 출력하고 구성한다.

주의 사항으로 SPA는 package.json 파일에 각종 설정들을 구성하게 된다. proxy를 통해 Access-Control-Allow-Origin 등의 API 호출을 위한 CORS 차단 등의 설정이 package.json에 함께 구성되는데 서버 배포시에는 해당 설정이 함께 반영되지 않는다. 즉 로컬에서만 설정을 반영할 수 있다. 따라서 해당 설정은 꼭 배포되는 Apache HTTPD 서버 등에 대체되는 설정으로 반영해야 한다.


결론

SPA는 Single Page Application으로 정적 컨텐츠를 서비스하는 모든 미들웨어에서 서비스가능하다. 또한 배포 체계는 기존 Maven 빌드 체계와 다음과 같이 비교된다.

- Maven Install to NPM Build

- Maven Build to NPM Run Build 

위와 같은 과정이 진행되면 이후는 일반 Apache HTTPD 서버에 배포하는 과정과 동일하다고 볼 수 있다. 물론 SPA의 경우 Single Page Application으로 기존 배포 방식과는 다르게 Context가 관리되므로 디렉토리 구조를 명확하게 가져가야한다. 일반적인 Static 서비스의 경우 디렉토리 구조를 기반으로 처리가 가능하므로 Static 파일 복사 후 디렉토리 구조에 맞게 호출이 가능하지만, SPA Application의 경우 Context를 Application에서 지정한데로 서비스 되어야 하므로 반드시 사전에 정책을 마련하여 개발하고 배포해야 한다.

728x90
반응형