likes
comments
collection
share

基于oneDev的自动发布

作者站长头像
站长
· 阅读数 10

为什么需要自动发布?

我们项目开发过程中需要经历很多次迭代,其中需要发布很多个版本,这个时候就涉及到代码的打包发布,传统的方式就是手动打jar/war包,完成之后去服务器进行手动发布,但是如果发布的版本比较多,这个过程就比较繁琐,每次都是一样的工作,但是需要一样的时间,因此可以引入自动发布来解决这个问题,每次写完代码之后点击一键发布即可解决我们的问题。

前期准备工作

安装虚拟机

首先需要安装两台虚拟机,安装docker、设置静态IP、安装常用指令。 详情见: juejin.cn/post/724803…

搭建oneDev

环境搭建好之后,启动第一台,安装oneDev并初始化一个项目 详情见:juejin.cn/post/724809…

两台centOS免密码传文件

实现自动发布的过程中需要用到2个操作

  • ssh 远程操作
  • scp 复制文件

详情见:juejin.cn/post/724815…

实现流程

初始状态

  • 有两台虚拟机:虚拟机A,虚拟机B
  • 虚拟机A里有oneDev的镜像,还有我们构建好的带有javamavensshscp的镜像;有一个运行中的oneDev的容器
  • 虚拟机B里没有镜像和容器 基于oneDev的自动发布

启动自动部署

  • 启动oneDev的自动发布,使用预设好的image,生成container
  • oneDev把代码拷贝到生成的container中
  • 执行oneDev上预设好的脚本,用maven打包项目,并且把生成的jar包、项目中的Dockerfile、docker.sh复制到虚拟机B中
  • 通过ssh让虚拟机B执行docker.sh,停止并删除旧版本的container,删除旧的images,通过Dockerfile和jar包生成新的image
  • 根据新的image生成container并且运行
  • 删除虚拟机A中临时使用的container

基于oneDev的自动发布

在我们的项目中加入docker.shDockerfile,用于打包完成之后启动项目,如果服务器上有jdk的环节,也可以直接java -jar xxx.jar 把项目跑起来

基于oneDev的自动发布

docker.sh

#!/bin/sh  
SERVER_NAME=auto-project  
SERVER_VERSION=0.0.1  
SERVER_PORT=8080  
SERVER_PORT_OUT=8080  
SERVER_DATA_PATH=/data/${SERVER_NAME}/data  
SERVER_DOCKER_IMAGE=${SERVER_NAME}:${SERVER_VERSION}  
  
docker stop ${SERVER_NAME}  
docker rm ${SERVER_NAME}  
docker rmi ${SERVER_DOCKER_IMAGE}  
  
echo "build docker image start ..."  
docker build -t ${SERVER_DOCKER_IMAGE} .  
echo "build docker image end ..."  
  
echo "start rum docker ..."  
mkdir -p ${SERVER_DATA_PATH}  
chmod 777 -R ${SERVER_DATA_PATH}  
docker run --tty -d --name ${SERVER_NAME} --restart=always -v ${SERVER_DATA_PATH}:/data --net=host -p ${SERVER_PORT_OUT}:${SERVER_PORT} ${SERVER_DOCKER_IMAGE}  
echo "start end docker ..."

Dockerfile

FROM openjdk:8  
MAINTAINER szq  
ADD ./demo-0.0.1-SNAPSHOT.jar auto-project.jar  
EXPOSE 8080  
VOLUME /data  
ENTRYPOINT java -jar auto-project.jar

上面的环境搭建好之后,就可以进入到自动发布的搭建流程,此时分为:虚拟机A(192.168.0.169)、虚拟机B(192.168.0.187),其中A是启动oneDev的虚拟机

  1. 在虚拟机A上准备一个Dockerfile,用于构建image:ci
FROM centos:7
# 安装Java
RUN yum -y update && \
    yum -y install java-1.8.0-openjdk-devel && \
    yum clean all
# 安装ssh和scp
RUN yum -y install openssh-server openssh-clients
# 安装Maven
ENV MAVEN_VERSION 3.8.8 
ENV MAVEN_HOME /usr/share/maven 
ENV PATH ${MAVEN_HOME}/bin:${PATH} 
RUN curl -fsSL "https://mirrors.aliyun.com/apache/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz" | tar xzf - -C /usr/share && \
    mv /usr/share/apache-maven-${MAVEN_VERSION} /usr/share/maven && \
    ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
# 配置Maven镜像源
COPY settings.xml /root/.m2/settings.xml
# 设置工作目录
WORKDIR /app
# 运行一个测试命令
CMD ["mvn", "--version"]
  1. 在同目录下准备一个settings.xml,用于自定义maven的下载镜像地址
<?xml version="1.0" encoding="UTF-8"?> 
<settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                              http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <mirrors>
    <mirror>
      <id>aliyun</id>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>*</mirrorOf>
    </mirror>
  </mirrors> 
</settings>

如下图所示: 基于oneDev的自动发布

  1. 构建镜像

执行docker build -t ci:1.0 .,因为Dockerfile的文件名为默认的,所以可以不用docker build -f Dockerfile -t ci:1.0 . 构建完成之后会得到一个镜像 基于oneDev的自动发布

  1. 根据镜像创建容器

docker create -it 84be8567a708 /bin/bash

docker start bd7ccea6a05e90c

可以看到镜像已经启动了: 基于oneDev的自动发布

进入容器查看我们的环境是否都搭建好了,如下图所示

基于oneDev的自动发布 可以看到我们的mavenjavasshscp都准备好了,我们测试完这个镜像之后就可以把这个容器停止并删除了

  1. 编写自动化部署脚本 打开oneDev,选择我们创建好的项目,可以看到这里有个提示,我们可以点击它添加我们的自动化部署脚本

基于oneDev的自动发布

基于oneDev的自动发布

step1:检出代码,把代码拷贝到临时生成的container中,下文用虚拟机C指代 基于oneDev的自动发布

这里输入个步骤名,其他默认即可 基于oneDev的自动发布

step2:执行我们自定义的命令,这里代码拷贝到虚拟机C之后,在虚拟机C中执行的命令 基于oneDev的自动发布

基于oneDev的自动发布

然后在下方Commands输入如下指令

echo '查看当前目录:ls'
ls
echo '执行mvn clean install,打包项目'
mvn clean install
echo '查看当前目录:pwd,ls'
pwd
ls
echo '查看target文件里的内容:ls target'
ls target
echo '查看src/main/docker里面的内容:pwd,ls src/main/docker'
cd src/main/docker
pwd
ls
echo '查看 /onedev-build/workspace/target的内容'
ls /onedev-build/workspace/target
echo '查看 /onedev-build/workspace/src/main/docker的内容'
ls /onedev-build/workspace/src/main/docker
echo '开始创建ssh的目录'
mkdir -p /root/.ssh/
echo '创建/root/.ssh完成,入ssh目录并pwd'
cd /root/.ssh
pwd
echo '把known_hosts写入/root/.ssh'
echo '
192.168.0.187 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJe/b5BRbQatRGrnBgs3tY6WEZp+PFrdbB2XRiW1ZuV+YXK85SK8cfebG0c/x1AlJAoi/cfnB2+0VC4XrpbG0Pk=
' >> known_hosts
echo '写入known_hosts完成,查看known_hosts:cat known_hosts'
cat known_hosts
echo '把id_rsa写入/root/.ssh'
echo '
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA0o2u5OOw4euCHTMZt/Msr1WxAmjsAcgFEH4UnEY4Vf7qseGj
yn0U0jksccJ2NmFSOtI+if1oeJXu8TOgxEmR9o5bL23ZnDZPdR8MqiKUXt7QSeCe
89x+fEoqlZHJeA/fS4XzmYNGyuY937AeXoY58lCVfdxo1BuDNaOW1z8nPEWGI/f3
vNfrZ0mIRXo4GByAfZVXnC0fk3/KFjh7kWt2P8+VrhaMuYyY+1RraIEA0ROQ/hr9
ZvJuKY79deYPQY6KDuGdtZ93iZ4j69EyQwyp1CXsnLwkcqIoTbJKbl6rT98cEUk7
ZDhvv+hs7NToWtfbCJmLcmSLSEpMU19/DZcC+QIDAQABAoIBADNEBiJ7AfVwF0Uu
zQNJ9UZXsfqpO1WPsxP57uDCBDOEFvbqvqut2uT4wMaOF6RT++aQjGOizM4Xi481
B97jHuQOc0tQDt0HKD+XKMlAFCopTEPAqlMsC6wNjuLOFWTjUHYeDlsBaLo8ZzJQ
uoQ/YFqMnml/whJrBH6J709HdDErNz9gXiTSbIB1hvGx7A1qfuN8WUf3GLIfGBZW
2sa4Ct8Zg/DAnTqtFpAqni+Po/K2U/11A5OjXa9Bfe9+H5GBE/2rdRVCIvRKKdKV
1T7gAUnqfQGt0sVLwCKApit1SwnGatGcKryVWaYnrUMEkaMf127TpWdYF6kCFvXY
qTDoxHUCgYEA8fcuIXhtUHdDu+QPnJp07/kOgaeRlZKns2x92XJwXnlOANVA59yI
Hu9zHRe/PeTfhHD5d9NfyQtU7ID78t5IQAYBsnSvJ7Gb6Eq6wEbYO9EJBpDwRjNC
wRyLHZRKcuJ2EADefQLJeu8eZ4qg50d2wcAe1p1wlwkCon3qNRUChTMCgYEA3sQU
yDXfTDMpodi/TZR9vDgsd/hKm2P6VlTIG47miDxBpiMfDr5GFtkFQL13wyx3tSbf
P0PbAqOz5QPNM0FVP94MZPozeyMnHT9kABmLLBeem8OGXLapMcvkcOvMmJKbZZ3K
BKdIpEFHOxnRvuMAafw9vSRwScV8D4xW94Qr/yMCgYB8SfvoNXPxYVHpsbxTNQPc
QJKzBuBBdJOwFoqOp7oQzT7ELsaoUx+YxGbdCtWxdV9bKKz8YBdTrf5xfc/tcUCr
omo8wLM4MINlTv2exsVL9JQuS0UgyjP//il3iDS1zp3Wmpuumz/jZfC4Pv1nz82w
uH8evsCW1IoF7afgnGovAQKBgHjWaGeKQYx2HFk819jfea0F06loOCA+hWcbKkk4
pPi1pu7WElzO/foa0uyhWju2/WB4q5UH2998qXLLMx5gjDvO2W5VAmQDV45X+ojL
UmEiltjroRDdzL3EWjCe2CbTMBRZGWKY06C2AEug39PqEylquJrHD1oVFAzjFbHC
MpN9AoGBAKQwrOQZDxog7IKUZ/sB9QakNpXj77G4p0ruCMqZ4TAKlShlz5yI/63I
X+mgcXBZLx6kPQIC+YTy5f+cnJh8UaYI6CwiN6Q6MkMUVGYb2HAaFz7BEFGU3gyA
B4gNKV+u9uQsKZFgEb5K8UCFoZ7YlKEXBASeii9m/Pelk9WVZWES
-----END RSA PRIVATE KEY-----
' >> id_rsa
echo '写入id_rsa完成,查看id_rsa:cat id_rsa'
cat id_rsa
echo '把id_rsa.pub写入/root/.ssh------------------------------'
echo '
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSja7k47Dh64IdMxm38yyvVbECaOwByAUQfhScRjhV/uqx4aPKfRTSOSxxwnY2YVI60j6J/Wh4le7xM6DESZH2jlsvbdmcNk91HwyqIpRe3tBJ4J7z3H58SiqVkcl4D99LhfOZg0bK5j3fsB5ehjnyUJV93GjUG4M1o5bXPyc8RYYj9/e81+tnSYhFejgYHIB9lVecLR+Tf8oWOHuRa3Y/z5WuFoy5jJj7VGtogQDRE5D+Gv1m8m4pjv115g9BjooO4Z21n3eJniPr0TJDDKnUJeycvCRyoihNskpuXqtP3xwRSTtkOG+/6Gzs1Oha19sImYtyZItISkxTX38NlwL5 root@@localhost.localdomain
' >> id_rsa.pub 
echo '写入id_rsa.pub 完成,查看id_rsa.pub:cat id_rsa.pub'
cat id_rsa.pub
echo '给id_rsa.pub,id_rsa授权600:chmod 600 id_rsa.pub,chmod 600 id_rsa'
chmod 600 id_rsa.pub
chmod 600 id_rsa
echo '授权完成,开始复制文件'
ssh root@@192.168.0.187 "mkdir -p ~/project"
scp /onedev-build/workspace/src/main/docker/Dockerfile root@@192.168.0.187:~/project
scp /onedev-build/workspace/src/main/docker/docker.sh root@@192.168.0.187:~/project
scp /onedev-build/workspace/target/demo-0.0.1-SNAPSHOT.jar root@@192.168.0.187:~/project
echo '复制jar包、Dockerfile、docker.sh完成'
ssh root@@192.168.0.187 "cd ~/project && pwd && ls && chmod 777 docker.sh"
echo "复制并授权完成,执行docker.sh"
ssh root@@192.168.0.187 "cd ~/project && ./docker.sh"
echo '执行docker.sh完成-----------------------------------------'

如果执行过程中下载镜像的过程比较慢,可以设置docker的镜像并且重启docker再次尝试

执行完成之后,查看虚拟机B的docker,已经把我们的服务给启动起来了

基于oneDev的自动发布

然后到我们的计算机去访问,结果访问不到,但是我们在虚拟机里[root@localhost docker]# curl http://192.168.0.187:8080/hello已经可以成功了

基于oneDev的自动发布

所以这个时候想起来,可能是8080端口没有开放,因此现在去打开8080端口

CentOS 7 或以上版本默认使用 firewalld 防火墙,可以使用以下命令开放需要的端口:

  1. 首先确认防火墙是否启动并且处于运行状态: sudo systemctl status firewalld

  2. 添加端口,例如开放 8080 端口: sudo firewall-cmd --add-port=8080/tcp --permanent 上述命令会将8080端口以tcp协议的方式添加到firewall的规则中,并设置为永久生效。

  3. 重新加载防火墙配置: sudo firewall-cmd --reload

  4. 大功告成,可以成功访问到我们发布的项目了,现在修改一下然后重新发布试试 基于oneDev的自动发布

修改接口返回值进行,然后重新发布测试

基于oneDev的自动发布

基于oneDev的自动发布

基于oneDev的自动发布

访问测试,发布成功 基于oneDev的自动发布