Menu Close

PHP source deploy with jenkins

PHP source deploy with jenkins

 

꽤 오래전 얘기지만 사내 개발중인 웹서비스의 대부분이 php로 개발되고 있고 효과적이고 일관된 배포방법이 없을까 고민하다 직접 스크립트를 작성하게 되었다.
해당 배포 방법은 jenkins내에서 동작하며, jenkins내에서 제공되는 variables를 활용했다.
스크립트를 분석해보면 알겠지만 동작 방식은 간단하며, 이를 응용하면 php뿐 아니라 다른것들도 가능하다.

 

우선 간단히 동작방식을 설명하자면 빌드를 하게되면 Execute shell에 등록된 배포 스크립트가 실행되고 배포 스크립트는 서버 리스트에 있는 아이피를 읽으면서 반복문을 이용해 배포될 서버에 rsync를 이용하여 싱크되는 방식이다.

 

serverlist 파일과 배포 스크립트의 지속적인 관리를 위해 git에 프로젝트를 만들었다.
프로젝트명 : serverscript

배포스크립트 작성
파일명 : deployScriptMulti.bash

#!/bin/bash

## since 2015.06.29
## author fallboyz@umount.net

## script usage
## sh deployScript SOURCE_DIR
## ex)
## sh deployScript jenkins_project

if [ $1 ]
    then
    SOURCE_NAME=$1
else
    echo "Please enter the jenkins project name."
    exit
fi

## EXCLUDE DIRECTORY 체크
EXCLUDE_CUSTOM=""
if [ $# -gt 1 ]
then
    for i in $(seq 1 $#)
    do
        j="$"$i
        eval DIR=$j
        EXCLUDE_CUSTOM=$EXCLUDE_CUSTOM" --exclude="$DIR
    done
fi

SOURCE_DIR="/data/apps/src/jenkins/workspace/"${SOURCE_NAME}"/"

while read line
do
    arr=$(echo $line | tr " " "\n")
    TARGET_PATH=""
    TARGET_USER=""
    TARGET_PORT="22"
    i=0
    for p in $arr
    do
        i=$(($i+1))

        if [ "$i" = "1" ] && [ $SOURCE_NAME != $p ]
        then
            break
        fi

        if [ "$i" = "1" ]
        then
            continue
        fi

        if [ "$i" = "2" ]
        then
            TARGET_PATH=$(echo $p)
            continue
        fi

        if [ "$i" = "3" ]
        then
            TARGET_USER=$(echo $p)
            continue
        fi

        if [ "$i" = "4" ]
        then
            TARGET_PORT=$(echo $p)
            continue
        fi

        PROJECT_IP=$(echo $p)

        TARGET_DIR=${TARGET_USER}"@"${PROJECT_IP}":"${TARGET_PATH}
        EXCLUDE_OPTION="--exclude=.svn --exclude=.git --exclude=.gitignore"

        rsync -atrpz --omit-dir-times --stats --delete -e "ssh -p "${TARGET_PORT}" -i /data/apps/src/jenkins/.ssh/id_rsa" ${EXCLUDE_OPTION} ${EXCLUDE_CUSTOM} ${SOURCE_DIR} ${TARGET_DIR}

        # 디버깅용
        #echo "rsync -atrpz --omit-dir-times --stats --delete -e ssh -i /data/apps/src/jenkins/.ssh/id_rsa" ${EXCLUDE_OPTION} ${EXCLUDE_CUSTOM} ${SOURCE_DIR} ${TARGET_DIR}
        #echo "TARGET_USER="${TARGET_USER}"=="
        #echo "PROJECT_IP="${PROJECT_IP}"=="
        #echo "TARGET_PATH="${TARGET_PATH}"=="
        #echo "EXCLUDE_OPTION="${EXCLUDE_OPTION}"=="
        #echo "SOURCE_DIR="${SOURCE_DIR}"=="
        #echo "TARGET_DIR="${TARGET_DIR}"=="
        #echo "EXCLUDE_CUSTOM="${EXCLUDE_CUSTOM}"=="
        #rsync -atrpz --omit-dir-times --stats --delete -e "ssh -i /data/apps/src/jenkins/.ssh/id_rsa" ${EXCLUDE_OPTION} ${EXCLUDE_CUSTOM} ${SOURCE_DIR} ${TARGET_DIR}
        #echo "rsync -atrpz --omit-dir-times --stats --delete -e ssh -i /data/apps/src/jenkins/.ssh/id_rsa" ${EXCLUDE_OPTION} ${EXCLUDE_CUSTOM} ${SOURCE_DIR} ${TARGET_DIR}
        #rsync -atrpz --omit-dir-times --stats --delete -e ssh -i /data/apps/src/jenkins/.ssh/id_rsa --exclude=.svn /data/apps/src/je:/opt/HomePage/BITTRADE2/WebAppnsoft syncuser@61.78.62.120
        #echo $i "=" $p "=" $SERVER_PARAM "=" $TARGET_DIR "=" $SOURCE_DIR "=" $EXCLUDE_CUSTOM
    done
done < "/data/apps/src/jenkins/workspace/serverscript/projectscript/serverlistmulti.txt"

 

서버리스트 파일 작성
아래 샘플에서도 나와 있지만 서버IP 리스트를 필요한만큼 옆으로 계속 써주면 되며, 띄어쓰기에 유의하자.
또한 해당 파일은 개행타입은 unix(LF), 캐릭터셋은 utf8로 꼭 작성하기 바란다.

파일명 : serverlistmulti.txt

## 배포서버 리스트 파일
## since 2015.06.29
## author fallboyz@umount.net
## Usage : [jenkins_프로젝트명] [배포될_서버_디렉토리_경로] [배포할_서버의_리눅스_계정] [SSH_포트] [서버IP_1] [서버IP_2] [서버IP_3] [서버IP_4] ...

## sample list ##
## umount.net
QA_umount.net /data/www/umount.net umount 22 10.19.10.5
LIVE_umount.net /data/www/umount.net umount 22 10.19.11.5 10.19.11.6 10.19.11.7

## test.umount.net
QA_test.umount.net /data/www/test.umount.net umount 2222 172.16.11.5 172.16.11.6
#################

 

이제는 jenkins에도 프로젝트를 생성한다.
프로젝트명 : serverscript

구성에 들어가서 위에 생성한 gitlb 리포지토리를 등록 후 빌드를 한다.

serverscript-git

 

이제 실제 웹서비스 소스가 관리되는 프로젝트를 생성한다.
위 샘플 서버 리스트에 있는 것처럼 진행해본다.

프로젝트명 : QA_umount.net
구성에 들어가서 매개변수 사용에 체크를 한다.
참고로 매개변수는 String Parameter 를 이용하는대, 해당 플러그인이 없으면 설치해야 한다.

매개변수 명 : param
Default Value : [jenkins_프로젝트명] [exclude file or exclude directory]
Default Value sample : QA_umount.net /readme.txt /document /class/config.php

Default Value에 있는 exclude 영역은 필수항목이 아니며, 빌드시 임의 추가 가능하다.
또 샘플에서 보는 것 같이 필요시 띄어쓰기를 이용해서 Multi로 추가가 가능하다.

jenkin-deploy-param

 

다음으로 소스 코드 관리 영역에는 당연하겠지만 실제 웹서비스의 소스가 있는 git 리포지토리를 등록한다.

jenkin-deploy-source

 

마지막으로 가장 중요한 부분으로 실제 스크립트를 실행하는 Execute shell 영역이다.
Command는 간단하다.

sh /data/apps/src/jenkins/workspace/serverscript/projectscript/deployScriptMulti.bash $param

스크립트 파일도 jenkins 프로젝트로 존재하기 때문에 실제 해당 경로를 적어주고 위에서 작성한 매개변수를 뒤에 넣어준다.

jenkin-deploy-build

 

이제 준비가 모두 완료되었다. 빌드 with parameter 를 누르면 위에서 매개변수 설정한 것과 같은 화면이 나온다.
그냥 바로 빌드하기를 눌러도 되고, 위에서 얘기했듯이 exclude를 추가하고 빌드하기를 해도 된다.

jenkin-deploy-build

 

위와 같은 방식의 배포는 전직장에서 처음 제안하고 직접 시범을 보여주면서 개발자들을 설득했으며, 아직도 위의 방식으로 배포를 하고 있다.
현 직장도 이 방법을 통해 모든 웹서비스 소스들을 배포/관리 하고 있다.

참고로 위 배포 방법을 사용하기 전에 선행해야 할 조건이 있는데 바로 ssh key 인증을 통해 로그인 없이 접속 가능하도록 해야 한다.
즉, 젠킨스 서버에서 ssh key를 만들고 해당 키를 배포될 서버들에 등록해야 한다.
그리고 모든 서버에는 당연하겠지만 rsync 패키지가 설치되어 있어야 한다.

궁금증이 있다면 사이트에 링크되어 있는 오픈채팅방을 이용해도 된다.

 

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

This site uses Akismet to reduce spam. Learn how your comment data is processed.