参考
https://gitee.com/log4j/pig
https://gitee.com/y_project/RuoYi-Vue
https://segmentfault.com/a/1190000022530075
https://segmentfault.com/a/1190000022530083
docker部署流水线
简介
这篇文章以之前的白嫖敏捷开发体系 为基础,从注册使用云效和阿里云,代码托管,配置个人制品仓库(主要是Maven
)、个人镜像仓库,流水线创建整个流程来一遍。
代码管理
https://codeup.aliyun.com/
因为云效是为企业或是组织服务的,所以与GitHub
、Gitee
这些开放的代码托管平台不同,更加关注与内部的代码管理,更像是私有的GitLab
。
基本的代码仓库功能都是用的,权限管理,分支合并,代码检测,还可以配合流水线做自动化,更有为企业用户考虑的报表分析。
导入代码方式有下
导入代码
设置HTTPS
密码,或是SSH
公钥都可,这样就可以方便的进行代码克隆推送了。
制品仓库
https://packages.aliyun.com/
制品仓库
Maven仓库
默认就有生产库和非生产库,也就是稳定版release
和快照版snapshot
,不用多讲
配置
两个仓库任意点一个,进入设置即可,配置Maven
或是Gradle
都可,这里的配置说明已经非常详细了,我也没必要去复述了。
另外注意,这里有两种配置方式,说了不复述还是。。。😂。总之就是要注意认真看官方的文档说明,别自己漏掉了又去各种网站去搜,别人的答案也只是把官网的话重复一遍
1、推送(修改方式),适用于配置过setting.xml
,需要修改的
2、推送(覆盖方式),适用于未配置过setting.xml
,可直接覆盖配置
3、username
和password
已经为我们填好了,复制去做就行
Maven配置
推送
1 mvn clean install org.apache.maven.plugins:maven-deploy-plugin:2.8:deploy -DskipTests
NPM仓库
这个我就略过了,官网也很清楚的
Docker仓库
开启容器镜像服务
容器镜像服务
设置账号密码
访问凭证,设置一下固定密码或是临时密码即可
创建命名空间
命名空间,按要求创建就行
创建镜像仓库
命名空间可有多个镜像仓库,镜像由[Docker Registry 地址]/[仓库名]:[端口号][镜像名][标签]
组成,入下是DockerHub
中java
仓库,多个Tags
对应着多个版本
官方java仓库
基本信息
创建好镜像仓库,点进去就看到基本信息了,操作指南也是很明确的
镜像仓库基本信息
流水线
https://flow.aliyun.com/
流水线的创建可以通过流水线的入口也可以在代码管理中创建,都是一样的
1、创建模版
默认已经提供了很多模版,如果合适的话直接使用当然更方便,初次使用的话,还是建议使用快速配置流水线模版,用这个更能全面了解流水线可以做哪些事情。
2、选择技术框架
选择技术框架
我这里选择了Java
3、步骤选择,步骤可以先先选简单点,后面也是可以改的,我就不一一贴图了,直接开始示例了
测试阶段
Java构建并发布到Maven制品库
默认已经把制品库配置好了。
添加流水线源
这里有很多代码源可选,我使用的是Codeup
,然后选择代码仓库和默认分支,可以开启代码源触发,选择代码提交或是合并完成,默认分支是在使用代码源触发时直接使用的分支。
添加流水线源
创建任务
这里有很多种任务组可选,非常方便,对于Java
构建,发布到Maven
制品仓库选,Java
构建就好,其实选择发布Maven
二方库应该也没问题。
创建任务
设置任务名称,选择构建集群,下载流水线源选择,JDK
、Maven
版本选择,构建命令如下,其实就是之前Maven
制品仓库,仓库指南中推送的命令
1 mvn clean install org.apache.maven.plugins:maven-deploy-plugin:2.8:deploy -DskipTests
编辑任务
运行
设置了触发策略就会自动触发,这里我们手动触发试一下,点击-保存并运行就可。
查看流水线日志
流水线每个过程都有详细日志可查看,方便我们排查问题,这里展示了成功构建后的截图,检查Maven
制品仓库也会发现有了更新
流水线日志
Java镜像构建并部署
如标题所述,这个才是重头。前面提到的我就不多说了。另外多提一下,我这个项目是仿照着pig 这个开源微服务项目来组织的,使用的是Spring Cloud Alibaba
的那一套。
pom
同时在根pom.xml
中配置了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <profiles > <profile > <id > dev</id > <properties > <profiles.active > dev</profiles.active > <nacosNamespace > xxx</nacosNamespace > </properties > <activation > <activeByDefault > true</activeByDefault > </activation > </profile > <profile > <id > test</id > <properties > <profiles.active > test</profiles.active > <nacosNamespace > xxx</nacosNamespace > </properties > </profile > <profile > <id > prod</id > <properties > <profiles.active > prod</profiles.active > <nacosNamespace > xxx</nacosNamespace > </properties > </profile > </profiles >
application
application.yml
配置如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 server: port: 3301 spring: application: name: @artifactId@ cloud: nacos: discovery: server-addr: ${NACOS_HOST:nacos}:${NACOS_PORT:8848} namespace: @nacosNamespace@ group: @nacos.group@ config: server-addr: ${spring.cloud.nacos.discovery.server-addr} namespace: @nacosNamespace@ group: @nacos.group@ config: import: - optional:nacos:${spring.application.name}-${spring.profiles.active}.yml profiles: active: @profiles.active@ logging: config: classpath:log4j2-${spring.profiles.active}.xml
所以符合微服务部署前提。
同时项目默认环境总是dev
,如果需要使用不同环境,在Maven
构建时带上如下参数即可
前提大概就是这样,如果有时间我会把这个项目详细讲一讲(目前还在玩这个,还没结束)
Dockerfile
我的Dockerfile文件如下,目录就在项目根路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 FROM registry.cn-shanghai.aliyuncs.com/wnhyang/openjdk:8 -jreRUN mkdir -p /home/app WORKDIR /home/app ARG JAR_FILE=./target/okay-shortLink-service.jarCOPY ${JAR_FILE} app.jar EXPOSE 3301 ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom" ENTRYPOINT ["java" ,"-jar" ,"app.jar" ,"$JAVA_OPTS " ]
选择任务组
这里选择Java
镜像构建,默认添加任务组:Java
构建和镜像构建并推送至阿里云镜像仓库个人版
选择任务组
Java构建
这个改一下JDK
、Maven
版本就好,注意⚠️:我的Dockerfile
中ARG JAR_FILE=./target/okay-shortLink-service.jar
就是对应了构建物的路径和文件名,这个一定要对应的。构建名在pom
的build
中配置,构建完成都在target
目录下,Dockerfile
构建镜像时将构建物装进Docker
镜像,大概就是这个流程。
编辑Java构建
镜像构建并推送至阿里云镜像仓库个人版
这个很重要,服务连接不多讲了,按照步骤来就好,选择之前配置好的仓库,注意⚠️:仓库名要和项目一致,看一下我前面举的java
官方镜像例子,一个仓库就是一种镜像,依靠标签区分,我这里就是用了默认的${DATETIME}
为标签;Dockerfile
路径一定要正确,不明白路径的点一下小问号?会提示
Dockerfile路径为Dockerfile文件相对于代码库根目录所在路径,如META/config/Dockerfile或Dockerfile
镜像构建并推送至阿里云镜像仓库个人版
最后,任务还有输出,这里输出的是镜像名和镜像公网地址和镜像VPC地址,流线线承接就体现在这,上游输出,下游输入。
任务输出
Docker部署
选部署中选择Docker
部署
Docker部署
Docker部署编辑
主机组需要自己配置一下,我这里使用的华为云服务器,非阿里云主机要稍微麻烦一点,不过也就一点,按步骤来就行,不多提了。
执行用户需要注意,我目前试的,在docker
组的用户也是会运行失败的,所以我还是使用了root
。
Docker部署编辑
部署脚本命令如下
1 2 3 4 5 # 部署脚本会在部署组的每台机器上执行。一个典型Docker部署脚本如下: # 示例中使用的$image 是您在脚本下方的变量处定义的变量(上游输出或自定义) # docker run $image sh /home/app/deploy.sh restart $APP_NAME $APP_NAME $port $image;
变量可以自定义,也可以自己设置,这里image
就是上游输出。因为我只有一台机器所以部署策略相对于我没用,如果你有多台机器,可以设置一下。
部署配置
部署脚本
这个脚本就不详细解释了,这个要提前放在主机组中,部署命令对应,注意修改nacos地址哦
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 # !/bin/bash SH_NAME=$0 ACTION=$1 APP_NAME=$2 APP_LOG_NAME=$3 APP_PORT=$4 DOCKER_URL=$5 usage() { echo "Not Support this operation: "${ACTION} echo "Usage: ${SH_NAME} {start|stop|restart} {APP_NAME} {APP_LOG_NAME} {APP_PORT} {ENV_PROFILES}" } stop_app() { echo 'stopping......' # 获取容器id CONTAINER=`docker ps -a |grep "${APP_NAME}" | awk '{print $1}'` # -n 字符串不为空返回true # 删除容器 if [[ -n "${CONTAINER}" ]] then docker stop ${CONTAINER} docker rm ${CONTAINER} echo "The container named ${APP_NAME} has been stopped and deleted" else echo "The container named ${APP_NAME} does not exist" fi # 删除镜像 if [[ -n "${DOCKER_URL}" ]] then REPO_URL=`echo ${DOCKER_URL%%:*}` TAG_NAME=`echo ${DOCKER_URL##*:}` fi if [[ -n "${TAG_NAME}" ]] then IMAGE=`docker images | grep ${REPO_URL} | grep ${TAG_NAME} |awk '{print $3}'` else IMAGE=`docker images | grep ${REPO_URL}|awk '{print $3}'` fi if [[ -n "${IMAGE}" ]] then docker rmi ${IMAGE} echo "The image named ${APP_NAME} has been deleted" else echo "The image named ${APP_NAME} does not exist" fi } create_log_dir(){ #日志路径要真实存在 log_path="/home/app/logs/"${APP_LOG_NAME} mkdir -p ${log_path} echo "create a log path: ${log_path}" } start_app() { echo '镜像版本:'${DOCKER_URL} # 运行容器 docker run -v /home/app/logs:/home/app/logs \ -p ${APP_PORT}:${APP_PORT} \ --add-host nacos:你的nacos地址 \ --name ${APP_NAME} \ -d ${DOCKER_URL} CONTAINER_ID=`docker ps -a | grep -v "grep" | grep ${APP_NAME} | awk -F: '{print $1}' | awk '{print $1}' | head -n 1` if [[ -n "${CONTAINER_ID}" ]] then RESULT=`docker inspect -f '{{.State.Running}}' ${CONTAINER_ID}` if [[ ${RESULT} = 'true' ]] then echo "部署成功" exit fi fi echo "部署失败" } start() { create_log_dir start_app } stop() { stop_app } case "$ACTION" in start) start ;; stop) stop ;; restart) stop start ;; *) usage ;; esac
运行
部署单