对近期项目的发布运维进行总结,项目前后端分离,后端利用docker部署,运维目标为一键发布运行项目最新版本。
一、服务器环境
服务器版本
CentOS Linux release 7.6.1810 (Core)。
用户
app
测试项目
后端cms,前端cms-static
二、相关目录
项目运行目录:
/data/www/html/cms/
/data/www/html/cms-static/
项目附件目录,可软链接至NFS:
/data/file/cms/
项目日志目录:
/data/www/html/cms_logs/
运维目录:
/shell/
代码仓库目录:
/shell/code_review/cms/
/shell/code_review/cms-static/
运维主管目录,
下包含代码仓库、发布文件仓库、发布打包脚本等:
/shell/code_review/admin/
配置目录:
/config/cms/
脚本目录:
/shell/release/
以上目录权限均设置为:
drwxr-xr-x app app
三、发布脚本
后端发布脚本:
/shell/release/11.release.cms.sh
1 #!/bin/bash 2 3 [ `whoami` != app ] && echo "Please use user 'app', su app" && exit 4 5 SOURCE_DIR=/shell/code_review/cms/ 6 RELEASE_DIR_TMP=/tmp/dev/cms/ 7 RELEASE_DIR=/data/www/html/cms/ 8 9 [ -d $RELEASE_DIR_TMP ] || mkdir -p $RELEASE_DIR_TMP 10 11 cd $SOURCE_DIR ; git checkout . ; git pull 12 cd src/Cms.Web.Host 13 dotnet publish -c Release -o $RELEASE_DIR_TMP 14 15 if [ $? != 0 ] ; then 16 echo "Build Failure" 17 exit 18 else 19 echo "Build Success" 20 fi 21 22 docker-compose -f /shell/compose/cms/compose-cms.yml down 23 24 /usr/bin/rsync -togplar --delete-after --progress \ 25 --exclude=Thumbs.db \ 26 --exclude='.svn/' \ 27 --exclude='.git/' \ 28 --exclude='\.*' \ 29 --exclude='Logs/' \ 30 --exclude='appsettings.json' \ 31 $RELEASE_DIR_TMP $RELEASE_DIR \ 32 | sed 's/\r//g' \ 33 | sed '/to-check/d' \ 34 | sed '/sending incremental file list/d' \ 35 | sed '/building file list/d' \ 36 | sed '/ to consider/d' \ 37 | sed '/bytes\/sec/d' \ 38 | sed '/total size is /d' \ 39 | sed '/\/$/d' \ 40 | sed '/^$/d' \ 41 >> /shell/release/logs/release.dev.cms.rsync.`date +%F`.log 42 43 \cp -f /config/cms/cms/appsettings.json $RELEASE_DIR 44 45 docker-compose -f /shell/compose/cms/compose-cms.yml up -d
docker-compose配置文件:
/shell/compose/cms/compose-cms.yml
1 version: "2.2" 2 services: 3 #dotnet 4 cms: 5 user: app 6 environment: 7 - LANG=en_US.UTF-8 8 - ASPNETCORE_URLS='http://0.0.0.0:8010' 9 restart: always 10 network_mode: host 11 image: dotnet:v3.1.1 12 ports: 13 - "127.0.0.1:8010:8010" 14 #- "0.0.0.0:8010:8010" 15 volumes: 16 - "/data/:/data/" 17 - "/shell/:/shell/" 18 - "/config:/config" 19 - "/etc/localtime:/etc/localtime" 20 # mem_limit: 1024m 21 # extra_hosts: 22 # - "mysqlserverip:172.16.0.48" 23 container_name: cms 24 entrypoint: /shell/release/docker.start.cms.sh
docker入口脚本文件:
/shell/release/docker.start.cms.sh
1 #!/bin/bash 2 3 cd /data/www/html/cms 4 export ASPNETCORE_URLS='http://0.0.0.0:8010' 5 dotnet Cms.Web.Host.dll >> /data/www/html/cms_logs/Cms.`date +%F`.log#这里为项目启动日志,项目运行日志配置即log4net配置。
前端发布脚本:
/shell/release/13.release.cms-static.sh
1 #!/bin/bash 2 [ `whoami` != app ] && echo "Please use user 'app', su app" && exit 3 4 SOURCE_DIR=/shell/code_review/cms-static/ 5 RELEASE_DIR_TMP=/shell/code_review/cms-static/dist/ 6 RELEASE_DIR=/data/www/html/cms-static/ 7 8 [ -d $RELEASE_DIR_TMP ] || mkdir -p $RELEASE_DIR_TMP 9 10 cd $SOURCE_DIR 11 git checkout . 12 git pull 13 npm install 14 npm run build:prod 15 16 if [ $? != 0 ] ; then 17 echo "Build Failure" 18 exit 19 else 20 echo "Build Success" 21 fi 22 23 /usr/bin/rsync -togplarc --delete-after --progress \ 24 --exclude=Thumbs.db \ 25 --exclude='.svn/' \ 26 --exclude='.git/' \ 27 --exclude='\.*' \ 28 $RELEASE_DIR_TMP $RELEASE_DIR \ 29 | sed 's/\r//g' \ 30 | sed '/to-check/d' \ 31 | sed '/sending incremental file list/d' \ 32 | sed '/building file list/d' \ 33 | sed '/ to consider/d' \ 34 | sed '/bytes\/sec/d' \ 35 | sed '/total size is /d' \ 36 | sed '/\/$/d' \ 37 | sed '/^$/d' \ 38 >> /shell/release/logs/release.dev.cms-static.rsync.`date +%F`.log
四、拓展补充
1,项目配置文件
在上面的发布脚本中,有一步操作为 cp -f /config/cms/cms/appsettings.json $RELEASE_DIR ,即在程序发布后,复制最新的配置文件到发布目录。配置文件库与代码仓库分离,采用svn或git工具单独管理。
2,hosts文件
在配置文件中出现多次变量,存储于/etc/hosts文件。
172.16.0.45 mysqlserverip 172.16.0.46 redisserverip 172.16.0.47 appserverip 172.16.0.48 qzserverip 172.16.0.100 svn.mytest.com 172.16.0.101 gitlab.mytest.com 172.16.0.102 ldap.mytest.com 172.16.0.103 crowd.mytest.com
3,git配置
发布脚本中,有进入代码仓库目录拉取的动作,需要提前配置好app用户下的git免密。
1 echo "https://release-who-r-u:Not***@gitlab.mytest.com" > ~/.git-credentials 2 git config --global credential.helper store #会在用户根目录生成文件.gitconfig 3 cat ~/.git-credentials 4 cat ~/.gitconfig
4,nginx前置
互联网访问项目站点均经由nginx前置转发到app服务器相关端口,本文重点在于说明一键发布运维的建立,前置转发配置及前置相关性能分析优化等部分不做赘述。
5,传统发布脚本
前面介绍了利用docker容器进行发布,这里顺带再总结下传统的发布方式。
/shell/release/11.release.cms.sh
1 #!/bin/bash 2 3 SOURCE_DIR=/shell/code_review/cms/ 4 RELEASE_DIR_TMP=/tmp/dev/cms/ 5 RELEASE_DIR=/data/www/html/cms/ 6 7 [ -d $RELEASE_DIR_TMP ] || mkdir -p $RELEASE_DIR_TMP 8 9 cd $SOURCE_DIR ; git checkout . ; git pull ; cd ../ 10 11 cd cms/src/Cms.Web.Host/ 12 dotnet publish -c Release -o $RELEASE_DIR_TMP 13 14 if [ $? != 0 ] ; then 15 echo "Build Failure" 16 exit 17 else 18 echo "Build Success" 19 fi 20 21 /bin/bash /shell/release/21.restart.cms.sh stop 22 23 /usr/bin/rsync -togplar --delete-after --progress \ 24 --exclude=Thumbs.db \ 25 --exclude='.svn/' \ 26 --exclude='.git/' \ 27 --exclude='\.*' \ 28 --exclude='Logs/' \ 29 --exclude='appsettings.json' \ 30 $RELEASE_DIR_TMP $RELEASE_DIR \ 31 | sed 's/\r//g' \ 32 | sed '/to-check/d' \ 33 | sed '/sending incremental file list/d' \ 34 | sed '/building file list/d' \ 35 | sed '/ to consider/d' \ 36 | sed '/bytes\/sec/d' \ 37 | sed '/total size is /d' \ 38 | sed '/\/$/d' \ 39 | sed '/^$/d' \ 40 >> /shell/release/logs/release.dev.cms.rsync.`date +%F`.log 41 42 /bin/bash /shell/release/21.restart.cms.sh start
/shell/release/21.restart.cms.sh
1 #!/bin/bash 2 3 [ `whoami` != app ] && echo "Please use user 'app', su app" && exit 4 source /etc/profile 5 6 case "$1" in 7 stop) 8 # stop 9 pkill -f Cms.Web.Host.dll 10 sleep 2 11 [ `ps auxf |grep Cms.Web.Host.dll | grep -v grep | wc -l ` -gt 0 ] && pkill -9 -f Cms.Web.Host.dll 12 ;; 13 14 start) 15 # start 16 cd /data/www/html/cms 17 export ASPNETCORE_URLS='http://0.0.0.0:8010' 18 \cp /config/cms/cms/appsettings.json /data/www/html/cms/ 19 20 nohup dotnet Cms.Web.Host.dll >> /tmp/nohup.cms.`date +%F`.log 2>&1 & 21 sleep 1 22 ps -ef|grep Cms.Web.Host.dll 23 ;; 24 25 restart) 26 /bin/bash /shell/release/21.restart.cms.sh stop && /bin/bash /shell/release/21.restart.cms.sh start 27 ;; 28 *) 29 /bin/bash /shell/release/21.restart.cms.sh stop && /bin/bash /shell/release/21.restart.cms.sh start 30 ;; 31 esac 32 exit 0
6,一键打包
项目运维中除了直接发布运行的情形,还有一键发布打包上传最新版本程序文件的需求,可通过以下脚本实现,这里举例是发布后直接上传到了svn版本库。
/shell/code_review/admin/12.release.cms.sit.sh
1 #!/bin/bash 2 3 SOURCE_DIR=/shell/code_review/admin/my-repos/sit/ 4 RELEASE_DIR_TMP=/tmp/sit/cms/ 5 RELEASE_DIR_SVN=/shell/code_review/admin/updates/sit/code-release/cms/ 6 7 [ -d $RELEASE_DIR_TMP ] || mkdir -p $RELEASE_DIR_TMP 8 9 cd $SOURCE_DIR 10 cd cms ; git checkout . ; git pull ; cd ../ 11 12 cd cms/src/Cms.Web.Host/ 13 dotnet publish -c Release -o $RELEASE_DIR_TMP 14 15 if [ $? != 0 ] ; then 16 echo "Build Failure" 17 exit 18 else 19 echo "Build Success" 20 fi 21 22 /usr/bin/rsync -togplar --delete-after --progress \ 23 --exclude=Thumbs.db \ 24 --exclude='.svn/' \ 25 --exclude='.git/' \ 26 --exclude='\.*' \ 27 --exclude='Logs/' \ 28 --exclude='appsettings.json' \ 29 $RELEASE_DIR_TMP $RELEASE_DIR_SVN \ 30 | sed 's/\r//g' \ 31 | sed '/to-check/d' \ 32 | sed '/sending incremental file list/d' \ 33 | sed '/building file list/d' \ 34 | sed '/ to consider/d' \ 35 | sed '/bytes\/sec/d' \ 36 | sed '/total size is /d' \ 37 | sed '/\/$/d' \ 38 | sed '/^$/d' \ 39 >> /shell/release/logs/release.sit.cms.rsync.`date +%F`.log 40 41 cd $RELEASE_DIR_SVN 42 svn st | grep "? \+" && svn add `svn st | grep "? \+" | sed "s/? \+//" | grep -v " "` 43 svn st | grep "! \+" && svn delete `svn st | grep "! \+" | sed "s/! \+//" | grep -v " "` 44 svn st | grep "? \+" && svn add "`svn st | grep "? \+" | sed "s/? \+//" `" 45 svn st | grep "! \+" && svn delete "`svn st | grep "! \+" | sed "s/! \+//"`" 46 svn st && svn ci -m 'auto commit by script'