我的精益创业第二步--持续发布环境搭建

我的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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,800评论 6 342
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 废话不多说,开始实施... 一些基本知识需要自己实践完,进行自我补充和提高。在下一节会介绍原理。 文中所涉及到的l...
    ZNB_天玄阅读 3,284评论 2 10
  • 坐一趟绿皮火车去到远方 站台没有人等 我感到孤独和兴奋 旅行很美 我不是 一两只蚂蚁爬爬 爬到火车上 爬下来就迷路...
    后生执笔阅读 227评论 0 2
  • 直到有一天,遇见了一个男人,他愿意蹲在街上为你系鞋带,像爸爸一样疼爱你,做你喜欢的事,重视你的生日、你们的纪念日甚...
    yuanhuili阅读 323评论 0 0