웹 어플리케이션은 크게 두 프로젝트(Server, Front)로 구성되어있을 가능성이 높다.
내가 맡고 있는 제품(웹앱)을 기준으로 CI/CD 환경을 구성하는 방법에 대해 정리할 예정이다.
Docker에 대한 설명은 이전 포스트를 참고하기 바람.
Docker를 사용해 Jenkins와 DBMS 인스턴스의 가상화 환경을 구성할 것이다. 이를 위해 Docker와 Docker Compose 모듈 설치한다.
Jenkins는 웹 어플리케이션의 빌드/테스트 자동화 과정을 수행하게되며
개요에서 설명한 Server, Front 프로젝트를 통합하는 과정을 수행하게 된다.
=> Server, Front 프로젝트는 각각의 Repository를 가진 별도의 프로젝트이며 하나의 앱으로 동작하기 위해서는
소스 빌드 및 통합 과정이 반드시 필요하다.
Jenkins는 node.js, gradle, maven, ant 등 여러 환경의 빌드를 플러그인 형태로 지원하기 때문에
각 빌드 도구의 버전별로 프로젝트를 관리하기에도 용이하다.
Docker Compose는 Docker 가상화 컨테이너를 사전에 yaml 파일로 정의하여 실행하기 위한 도구이다.
사전에 yaml파일에 Docker 이미지, 컨테이너 이름, 호스트 서버-컨테이너 간 포트/볼륨 공유 설정,
전체 수명 주기를 관리 등을 정의한다.
Docker 컨테이너를 실행할 폴더를 생성하고 docker-compose-jenkins.yml
파일을 아래와 같이 작성한다.
# Docker 버전
version: '3'
# Docker 컨테이너 서비스 정의
services:
# 젠킨스 컨테이너 서비스 정의
jenkins:
# 젠킨스 이미지:태그
image: jenkins/jenkins:2.346
# 컨테이너 명
container_name: jenkins_edm
stdin_open: true
# 컨테이너 중단 시 자동 재시작
restart: always
# 볼륨 동기화
volumes:
- '/home/user/Docker/Jenkins_EDM/jenkins_home:/var/jenkins_home'
# 컨테이너 실행 USER
user: root:root
# 호스트:컨테이너 포트 매핑
ports:
- 8083:8080
# 컨테이너 환경변수
environment:
해당 yaml 파일을 사용해 Docker 컨테이너를 실행하는 쉘 파일 docker-jenkins.sh
을 아래와 같이 작성한다.
# docker-compose
## -f $1 : 파일 명시
## --build : 캐싱된 이미지가 아닌 이미지 빌드 후 시작
## -d : Docker 컨테이너 백그라운드 실행
case "$1" in
'start') # Start Jenkins Docker Container
echo "Start Jenkins Docker Container...: "
sudo docker-compose -f ./docker-compose-jenkins.yml up --build -d
# 직전 실행 커맨트 성공 값 (0 : 성공 / 1 : 실패)
RVAL=$?
echo $RVAL
exit $RVAL
;;
'stop') # Stop Jenkins Docker Container
echo "Stop Jenkins Docker Container...: "
sudo docker-compose -f ./docker-compose-jenkins.yml down
RVAL=$?
echo $RVAL
exit $RVAL
;;
'restart') # Restart Jenkins Docker Container
echo "Restart Jenkins Docker Container...: "
sudo docker-compose -f ./docker-compose-jenkins.yml down
sudo docker-compose -f ./docker-compose-jenkins.yml up --build -d
RVAL=$?
echo $RVAL
exit $RVAL
;;
esac
아래 명령어로 매개변수와 함께 sh파일을 실행하여 Jenkins 컨테이너를 실행한다.
~$ ./docker-jenkins.sh start
Docker 컨테이너 확인 명령어를 통해 아래와 같이 실행된 Jenkins 컨테이너를 확인할 수 있다.
~$ docker ps -a
// STATUS : Up 상태를 통해 정상적으로 실행된 상태임을 알 수 있다.
CONTAINER ID IMAGE COMMAND CREATED STATUS
12f2141e5d16 jenkins/jenkins:2.346 "/usr/bin/tini -- /u…" 3 months ago Up 5 weeks
PORTS NAMES
50000/tcp, 0.0.0.0:8083->8080/tcp, :::8083->8080/tcp jenkins_edm
=> 컨테이너를 실행중인 서버의 8083 포트로 접속 시 Jenkins 로그인 화면을 확인할 수 있다.
처음 젠킨스 컨테이너를 시작하고 접속하면 필요한 플러그인을 선택하고 설치를 진행하게 된다.
플러그인 간 의존성으로 처음부터 설치 요청한 모든 플러그인이 정상적으로 설치되지 않을 수 있다.
스킵하고 진행 하더라도 Jenkins 플러그인 관리메뉴에서 재설치가 가능하다.
Jenkins에서는 Job 이라는 단위의 Task를 생성하여 프로젝트를 빌드하고 통합하는 과정을 거치게 되므로
node.js, gradle, maven, ant 등 프로젝트 별 빌드에 필요한 플러그인을 설치해야한다.
Jenkins 대시보드 >> Jenkins 관리
메뉴로 진입한다.
플러그인 관리
를 클릭한다.
각자의 프로젝트 빌드 환경에 맞는 플러그인을 설치해준다.
나는 Gitlab, gradle, Apache Ant, NodeJS 플러그인을 설치해줄 것이다.
현재 레파지토리를 Gitlab으로 관리하고 있으므로 Gitlab 플러그인을 추가 설치해준다.
앞서 설치한 빌드 툴 플러그인을 Jenkins 전역에서 사용하기 위해
Jenkins 대시보드 >> Jenkins 관리 >> Global Tool Configuration
메뉴로 진입한다.
프로젝트에서 빌드에 사용하고 있는 gradle 버전에 맞게 버전을 선택하고
Jenkins Job에서 어플리케이션 빌드/통합 과정에서 참조할 gradle의 name을 입력하고 저장한다. \
단일 빌드 환경이라면 간단하게 gradle로 입력하면 된다.
다중 버전의 빌드 환경이라면 gradle 버전을 추가하고 configuration name을 다르게 저장하면 된다.
Apache Ant, NodeJS도 마찬가지로 설정해준다.
내 시스템에서 소스 레파지토리는 Gitlab에서 관리하고 있으므로 Jenkins에서 레파지토리에 접근하여
소스를 빌드하기 위해 Gitlab credential을 추가해야 한다.
젠킨스 대시보드 메뉴 중 Jenkins 관리
클릭
Security > Manage Credential
클릭
global scope
클릭 후 Add credential
클릭
아래 내용을 입력하고 Create
버튼을 눌러 프로젝트 레파지토리에 접근 가능한 Gitlab Credential을 등록한다.