我的精益創業第二步--持續發布環境搭建

我的CD

作為一個獨立的工程師,時間是最寶貴的,搭建一個高效的產品發布環境能節省很多重復的時間。
  現在有很多這樣的CD工具,可以管理較大的產品,對我來說,學習成本太大,經過仔細的考慮,我選擇使用shell腳本來實現簡單的CD!

基本配置

基本配置
  • 接下來就是安裝各種程序:lnmp,java,tomcat,maven,git;
  • 配置環境變量;

還有一些每次發布版本都需要重復的工作,比如:

  • 部署java的war包;
  • 重新啟動tomcat的服務;
    這些操作都比較簡單,但是很耗時間,對于快節奏的版本更新產品來說,是很大的資源浪費。

經過以上的思考,通過2天的時間編寫了一個shell如下腳本;實現了:

  • 自動安裝java和git環境
  • 自動拉取git上的最新代碼,通過maven進行遠程的源碼編譯
  • 自動發布和備份產品工程包
  • 自動安裝nodejs環境 v4.5的版本
  • 自動安裝cnpm來使用淘寶的源下載node模塊
  • 啟動web控制臺來執行指令(通過nodejs實現)

先創建一個目錄
$ mkdir -p /home/setups

#! /bin/sh
#定義顏色的變量
RED_COLOR='\E[1;31m'  #紅
GREEN_COLOR='\E[1;32m' #綠
YELOW_COLOR='\E[1;33m' #黃
BLUE_COLOR='\E[1;34m'  #藍
PINK='\E[1;35m'      #粉紅
RES='\E[0m'

# >>>>>>>>>>>>>>>>>>>>設置全局變量
# >>>>>>>>>>>>>>>>>> api代碼的目錄
# >>>>>>>>>>>>>>>>>> ci代碼庫目錄
# >>>>>>>>>>>>>>>>>> tomcat目錄
#清屏
clear

# 安裝文件的目錄
# 優先從安裝文件目錄中下載
SETUP_DIR="/home/setups"

# ci 的工作目錄
CI_HOME_DIR="/home/ci/java"
CI_LIB_DIR="$CI_HOME_DIR/lib"
CI_TARGET_DIR="$CI_HOME_DIR/target"
CI_LOG_DIR="$CI_HOME_DIR/log"
CI_CONF_FILE="$CI_HOME_DIR/ci.conf"

# maven 的相關變量定義
MAVEN_VERSION="apache-maven-3.3.9"
MAVEN_TAR="$MAVEN_VERSION-bin.tar.gz"
MAVEN_DOWNLOAD_URI="http://mirrors.cnnic.cn/apache/maven/maven-3/3.3.9/binaries/$MAVEN_TAR"
MAVEN_DIR="$CI_LIB_DIR/$MAVEN_VERSION"

# tomcat的相關變量的定義
TOMCAT_VERSION="apache-tomcat-8.5.4"
TOMCAT_TAR="$TOMCAT_VERSION.tar.gz"
TOMCAT_DOWNLOAD_URI="http://mirrors.cnnic.cn/apache/tomcat/tomcat-8/v8.5.4/bin/$TOMCAT_TAR"
TOMCAT_HOME_DIR="$CI_LIB_DIR/$TOMCAT_VERSION"
TOMCAT_DEPLOY_DIR="$TOMCAT_HOME_DIR/webapps"
TOMCAT_PORT="8080"

# jdk的相關變量的定義
JAVA_VERSION="jdk1.8.0_102"
JAVA_TAR="jdk-8u102-linux-x64.tar.gz"
JAVA_DOWNLOAD_URI="http://download.oracle.com/otn-pub/java/jdk/8u102-b14/$JAVA_TAR"
JAVA_HOME_DIR="$CI_LIB_DIR/$JAVA_VERSION"

# 需要讀取相關的配置文件
if [ -f $CI_CONF_FILE ]; then
  TOMCAT_HOME_DIR=`grep 'TOMCAT_HOME=' $CI_CONF_FILE`
  TOMCAT_HOME_DIR=${TOMCAT_HOME_DIR#*=}
  TOMCAT_PORT=`grep 'TOMCAT_PORT=' $CI_CONF_FILE`
  TOMCAT_PORT=${TOMCAT_PORT#*=}
  TOMCAT_DEPLOY_DIR="$TOMCAT_HOME_DIR/webapps"
fi


# 項目名稱
PROJECT_NAME="yfoa"
# 項目的變量定義
PROJECT_GIT="https://git.oschina.net/***.git"
PROJECT_DIR="$CI_HOME_DIR/$PROJECT_NAME"
PROJECT_SOURCE_DIR=$PROJECT_DIR
PROJECT_TARGET_DIR="$PROJECT_SOURCE_DIR/target"
PROJECT_TARGET_VERSION_CODE=`date '+%m%d%H%M'`

# 定義相關的函數
# 返回 0 表示操作成功,小于 0 的所有返回值,均為執行錯誤

# 安裝操作
function ciInstall {
  ### 創建CI工作區
  echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>>      Create CI Dir    >> >>>>>>>>>>>>>>>>${RES}"
  #放心執行,因為已經存在的忽略掉的
  mkdir -p $CI_HOME_DIR
  mkdir -p $CI_LIB_DIR
  mkdir -p $CI_TARGET_DIR
  mkdir -p $CI_LOG_DIR

  ### 安裝 jdk 1.8
  #判斷是否安裝過 jdk
  if [ ! -d $JAVA_HOME_DIR ]; then
    echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>>      Install JDK    >> >>>>>>>>>>>>>>>>${RES}"
    cd $CI_LIB_DIR
    if [ -f $SETUP_DIR/$JAVA_TAR ]; then
      cp $SETUP_DIR/$JAVA_TAR $CI_LIB_DIR/$JAVA_TAR
    else
      wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" -O $JAVA_TAR $JAVA_DOWNLOAD_URI
    fi

    tar -zxvf $JAVA_TAR
    # TODO:修改環境變量
    echo "JAVA_HOME=$JAVA_HOME_DIR" >> /etc/profile
    echo 'PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile
    echo 'CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar' >> /etc/profile
    echo "export JAVA_HOME PATH CLASSPATH" >> /etc/profile
    source /etc/profile
    java -version
  else
    echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>>       JDK Installed   >> >>>>>>>>>>>>>>>>${RES}"
  fi

  ### 安裝 tomcat
  #判斷是否安裝過 tomcat
  if [ ! -d $TOMCAT_HOME_DIR ]; then
    echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>>      Install Tomcat    >> >>>>>>>>>>>>>>>>${RES}"
    cd $CI_LIB_DIR
    if [ -f $SETUP_DIR/$TOMCAT_TAR ]; then
      cp $SETUP_DIR/$TOMCAT_TAR $CI_LIB_DIR/$TOMCAT_TAR
    else
      wget $TOMCAT_DOWNLOAD_URI
    fi

    tar -zxvf $TOMCAT_TAR
  else
    echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>>       Tomcat Installed   >> >>>>>>>>>>>>>>>>${RES}"
  fi


  ### 安裝 maven
  #判斷是否安裝過maven
  if [ ! -d $MAVEN_DIR ]; then
    echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>>      Install Maven    >> >>>>>>>>>>>>>>>>${RES}"
    cd $CI_LIB_DIR
    if [ -f $SETUP_DIR/$MAVEN_TAR ]; then
      cp $SETUP_DIR/$MAVEN_TAR $CI_LIB_DIR/$MAVEN_TAR
    else
      wget $MAVEN_DOWNLOAD_URI
    fi
    tar -zxvf $MAVEN_TAR
  else
    echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>>       Maven Installed   >> >>>>>>>>>>>>>>>>${RES}"
  fi

  ### 安裝 git & lsof
  echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>>      Install Git & LSOF    >> >>>>>>>>>>>>>>>>${RES}"
  yum install git
  yum install lsof
  echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>>       Git & LSOF Installed   >> >>>>>>>>>>>>>>>>${RES}"

  ### 下載代碼
  if [ ! -d $PROJECT_DIR ]; then
    echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>>      Download Code From Git : >$PROJECT_GIT< ${RES}"
    cd $CI_HOME_DIR
    git clone $PROJECT_GIT $PROJECT_NAME
  fi
  echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>>       Code Downloaded ${RES}"

  echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>>     Install Down ${RES}"
  echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>>     New You Can Build The Project ${RES}"
  echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>>     $ ci build ${RES}"
  return 0
}

# 配置設置
function ciConfig {
  echo -e "${PINK}請輸入tomcat的所在目錄(默認:$TOMCAT_HOME_DIR)? ${RES}"
  read -p ":" _tomcatHome
  if [ -z $_tomcatHome ]; then
    echo -e "${PINK}確認要使用默認的安裝目錄: $TOMCAT_PORT?${RES}"
    read -p "[y/n]:" isYN
    if [ ! $isYN = "y" ]; then
      echo -e "${PINK}[ERROR]您已放棄本次配置,請在下一次部署工程前完成配置,否則將無法部署 ${RES}"
      return 11
    else
      TOMCAT_HOME_DIR="$TOMCAT_HOME_DIR"
    fi
  else
    TOMCAT_HOME_DIR=$_tomcatHome
  fi
  echo -e "${PINK}請輸入tomcat所使用的端口(默認:$TOMCAT_PORT)?${RES}"
  read -p  ":" _tomcatPort
  if [ -z $_tomcatPort ]; then
    echo -e "${PINK}確認要使用默認的端口號: $TOMCAT_PORT?${RES}"
    read -p "[y/n]:" isYN
    if [ ! $isYN = "y" ]; then
      echo -e "${PINK}[ERROR]您已放棄本次配置,請在下一次部署工程前完成配置,否則將無法部署 ${RES}"
      return 12
    else
      TOMCAT_PORT="$TOMCAT_PORT"
    fi
  else
    TOMCAT_PORT=$_tomcatPort
  fi
  # 寫入文件
  rm -f $CI_CONF_FILE
  echo "TOMCAT_HOME=$TOMCAT_HOME_DIR" > $CI_CONF_FILE
  echo "TOMCAT_PORT=$TOMCAT_PORT" >> $CI_CONF_FILE
  return 0
}

# 清空ci工作區的所有文件,慎用
function ciClean {
  if [ ! -d $CI_HOME_DIR ]; then
    #該目錄已經不存在
    echo -e "${PINK}目錄 : $CI_HOME_DIR 已不存在,無需刪除~ ${RES}"
    return 22
  fi
  echo -e "${PINK}確認要清除CI目錄[$CI_HOME_DIR]么?${RES}"
  read -p "[y/n]:" isYN
  if [ $isYN = "y" ]; then
    rm -rf $CI_HOME_DIR
  else
    echo "Bye"
    return 21
  fi
  return 0
}

# 清楚ci工作區的 target & log目錄
function ciClear {
  echo -e "${PINK}確認要清除CI目錄的日志和目標文件么?${RES}"
  read -p "[y/n]:" isYN
  if [ $isYN = "y" ]; then
    rm -rf $CI_HOME_DIR/log/*
    rm -rf $CI_HOME_DIR/target/*
  else
    echo "Bye"
    return 31
  fi
  return 0
}

# 構建項目
function ciBuild {
  echo -e "${BLUE_COLOR}[GO]>>>>>>      Clean${RES}"
  # 清空target目錄下的文件
  rm -rf $PROJECT_TARGET_DIR/*
  if [ -f $CI_TARGET_DIR/$PROJECT_NAME_deploy.war ]; then
    rm -f $CI_TARGET_DIR/$PROJECT_NAME_deploy.war
  fi
  echo -e "${GREEN_COLOR}[OK]>>>>>>     Clean done${RES}"
  #下拉代碼
  cd $PROJECT_DIR
  echo -e "${BLUE_COLOR}[GO]>>>>>>      Pull the master source code      ${RES}"
  git pull origin master
  echo -e "${GREEN_COLOR}[OK]>>>>>>     Pull done     ${RES}"

  echo -e "${BLUE_COLOR}[GO]>>>>>>      Build start      ${RES}"
  #編譯代碼
  cd $PROJECT_SOURCE_DIR
  $MAVEN_DIR/bin/mvn package > $CI_LOG_DIR/MAVEN_PACKAGE_$PROJECT_TARGET_VERSION_CODE.log
  echo -e "${GREEN_COLOR}[OK]>>>>>> Build done           ${RES}"
  #ls -l $API_TARGET_DIR
  echo -e "${BLUE_COLOR}[GO]>>>>>> Copy to target dir     ${RES}"
  # 這里需要替換成相應的tomcat的目錄
  cp $PROJECT_TARGET_DIR/$PROJECT_NAME.war $CI_TARGET_DIR/$PROJECT_NAME_$PROJECT_TARGET_VERSION_CODE.war
  cp $PROJECT_TARGET_DIR/$PROJECT_NAME.war $CI_TARGET_DIR/$PROJECT_NAME_deploy.war
  echo -e "${GREEN_COLOR}[OK]>>>>>> Target Version : $PROJECT_TARGET_VERSION_CODE"
  echo -e "${GREEN_COLOR}[OK]>>>>>> You Need TO Deploy       ${RES}"
  echo -e "${GREEN_COLOR}[OK]>>>>>> Like: $ ./ci.sh deploy       ${RES}"

  return 0
}

function ciStartServer {
  echo -e "${BLUE_COLOR}[GO]>>>>>> Shutdown Server          ${RES}"
  $TOMCAT_HOME_DIR/bin/shutdown.sh
  # 有時候會關閉掉,導致重啟不了
  # 使用lsof強制進行關閉
  pid=`lsof -t -i:$TOMCAT_PORT`
  if [ ! -z $pid ]; then
    kill -9 $pid
  fi
  $TOMCAT_HOME_DIR/bin/startup.sh
  echo -e "${GREEN_COLOR}[OK]>>>>>>  Startup ok          ${RES}"

  return 0
}

# 復制工程并重啟tomcat
function ciRestart {
  if [ -z $1 ]; then
    target_war="$CI_TARGET_DIR/$PROJECT_NAME.war"
  fi
  echo "target_war  $target_war"
  if [ ! -f $target_war ]; then
    echo -e "${PINK}[ERROR]>>>>>> Cant Find The TargetWar File~ You Need Run The Next Command:        ${RES}"
    echo -e "${GREEN_COLOR}[OK]>>>>>> $ ./ci.sh build       ${RES}"
    return 52
  fi

  echo -e "${BLUE_COLOR}[GO]>>>>>> Shutdown tomcat          ${RES}"
  # 有時候會關閉掉,導致重啟不了
  # 使用lsof強制進行關閉
  pid=`lsof -t -i:$TOMCAT_PORT`
  if [ ! -z $pid ]; then
    $TOMCAT_HOME_DIR/bin/shutdown.sh
    kill -9 $pid
  fi
  echo -e "${GREEN_COLOR}[OK]>>>>>>  Shutdown ok          ${RES}"

  cp $target_war $TOMCAT_DEPLOY_DIR/$PROJECT_NAME.war

  $TOMCAT_HOME_DIR/bin/startup.sh

  if [ ! -f $TOMCAT_DEPLOY_DIR/$PROJECT_NAME.war ]; then
    echo -e "${PINK}[ERROR]>>>>>> Deploy failed~ plz run again        ${RES}"
    return 51
  else
    echo -e "${GREEN_COLOR}[OK]>>>>>> Success~ Deploy Finished~          ${RES}"
  fi
  return 0
}

# 手動部署項目
function ciDeploy {
  target_war="$CI_TARGET_DIR/$PROJECT_NAME.war"
  if [ ! -z $1 ]; then
    echo $1
    target_war="$CI_TARGET_DIR/$1.war"
  fi
  echo $target_war
  echo -e "${GREEN_COLOR}[GO]>>>>>> Deploy          ${RES}"
  echo -e "${GREEN_COLOR}[GO]>>>>>>  The Tomcat Var Is:          ${RES}"
  echo -e "${GREEN_COLOR}[OK]>>>>>>  TOMCAT_HOME_DIR At $TOMCAT_HOME_DIR ${RES}"
  echo -e "${GREEN_COLOR}[OK]>>>>>>  TOMCAT_PORT     At $TOMCAT_PORT ${RES}"
  echo -e "${GREEN_COLOR}[OK]>>>>>>  TOMCAT_DEPLOY_DIR     At $TOMCAT_DEPLOY_DIR ${RES}"
  echo -e "${GREEN_COLOR}[OK]>>>>>>  是否使用當前環境變量進行發布?${RES}"
  read -p "[y/n]:" isYN
  if [ ! $isYN = "y" ]; then
    echo -e "${GREEN_COLOR}[OK]>>>>>>  請輸入 $ ci.sh conf 重新配置tomcat的目錄${RES}"
    return 41
  fi

  ciRestart $target_war

  return $?
}

# 自動部署項目
function ciPublish {
  ciRestart
  return $?
}

function ciRequireCommand {
  echo -e "${GREEN_COLOR}[GO]>>>>>>  您輸入的參數錯誤,可選的參數如下:         ${RES}"
  echo -e "${GREEN_COLOR}[GO]>>>>>>  ci install  : 安裝ci目錄,maven,下載git代碼          ${RES}"
  echo -e "${GREEN_COLOR}[GO]>>>>>>  ci build  :編譯git倉庫中最新的代碼 ${RES}"
  echo -e "${GREEN_COLOR}[GO]>>>>>>  ci deploy :將代碼發布到servlet容器中并重啟該容器 ${RES}"
  echo -e "${GREEN_COLOR}[GO]>>>>>>  ci conf :設置servlet容器的目錄和端口 ${RES}"
}
echo -e "${BLUE_COLOR}[GO]>>>>>>>>>>>> Command:[$1]>>>>>>>>>>>>>>${RES}"

#沒有值
if [ -z $1 ]; then
  ciRequireCommand
  exit
## 安裝流程
elif [ $1 = "install" ]; then

  ciInstall

elif [ $1 = "conf" ]; then

  ciConfig
  if [ $? > 0 ]; then
    exit
  fi
elif [ $1 = "startup" ]; then
  ciStartServer
  if [ $? > 0 ]; then
    exit
  fi
elif [ $1 = "clean" ]; then
  ciClean
  if [ $? > 0 ]; then
    exit
  fi

elif [ $1 = "clear" ]; then
  ciClear
  if [ $? > 0 ]; then
    exit
  fi
elif [ $1 = "build" ]; then
  ciBuild
elif [ $1 = "deploy" ]; then
  ciDeploy $2
elif [ $1 = "publish" ]; then
  ciPublish
  if [ $? > 0 ]; then
    exit
  fi
else
  ciRequireCommand
  exit
fi #end if

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,941評論 6 342
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,869評論 18 139
  • 廢話不多說,開始實施... 一些基本知識需要自己實踐完,進行自我補充和提高。在下一節會介紹原理。 文中所涉及到的l...
    ZNB_天玄閱讀 3,313評論 2 10
  • 坐一趟綠皮火車去到遠方 站臺沒有人等 我感到孤獨和興奮 旅行很美 我不是 一兩只螞蟻爬爬 爬到火車上 爬下來就迷路...
    后生執筆閱讀 262評論 0 2
  • 直到有一天,遇見了一個男人,他愿意蹲在街上為你系鞋帶,像爸爸一樣疼愛你,做你喜歡的事,重視你的生日、你們的紀念日甚...
    yuanhuili閱讀 332評論 0 0