Drone 部署 Spring boot 服务多环境配置
环境准备
流程
流程图
mermaid
graph TB
st(开始)e(结束)
st-->push(提交代码)st-->tag(提交 Tag)push-->op1(Maven 打包项目 生成 Jar 包文件)tag-->op1op1-->condService(是否是服务)condService-->|否|sub1(发布 Jar 包到私服仓库)condService-->|是|condTag("构建发布镜像")condTag-->|是|op2(发布 Git 版本)condTag-->|否|op3(拷贝 docker-compose.yml 到目标服务器)op2-->op3op3-->op4(连接目标服务器运行)
sub1-->eop4-->e环境配置
Maven 配置
开发过程中可能回有多个 Java 版本的情况,以及会使用一些代理仓库加速下载依赖,构建一些内部常用的 Maven 环境
本文以 eclipse-temurin-8-alpine 为例,GitHub 查看更多版本
下载 Dockerfile,mvn-entrypoint.sh 文件,
wget https://raw.githubusercontent.com/carlossg/docker-maven/master/eclipse-temurin-8-alpine/Dockerfilewget https://raw.githubusercontent.com/carlossg/docker-maven/master/eclipse-temurin-8-alpine/mvn-entrypoint.shsettings.xml 添加自定义设置文件
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd"> <localRepository>/usr/share/maven/ref/repository</localRepository>
<servers> <server> <id>private-repo</id> <!-- 仓库 ID,与 pom.xml 中配置的 repository id 匹配 --> <username>your-username</username> <password>your-password</password> </server> </servers> <mirrors> <mirror> <id>mirror-repo</id> <mirrorOf>*</mirrorOf> <name>mirror repo</name> <url>http://nexus.domain.com/repository/maven-mirror-repo/</url> </mirror> </mirrors> <profiles> <profile> <id>private-repo-profile</id> <repositories> <repository> <id>private-repo</id> <!-- 仓库 ID,与 servers 中的 id 匹配 --> <url>http://nexus.domain.com/repository/maven-private-repo/</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>true</enabled></snapshots> </repository> </repositories> </profile> </profiles> <activeProfiles> <activeProfile>private-repo-profile</activeProfile> </activeProfiles></settings>修改 Dockerfile
FROM eclipse-temurin:8-jdk-alpine
# 国内网络问题,使用 aliyun 源RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache curl tar bash procps
# ...
COPY mvn-entrypoint.sh /usr/local/bin/mvn-entrypoint.sh# 添加自定义配置文件COPY settings.xml /usr/share/maven/conf/
ENTRYPOINT ["/usr/local/bin/mvn-entrypoint.sh"]CMD ["mvn"]打包成镜像
docker build -t ci/maven:8-jdk .配置部署模板文件
生成 Dockerfile,docker-compose.yml 等文件相关脚本,可以更具自己实际需求更改
Dockerfile.tmpl
FROM <% ${FROM_IMAGE} %>
ADD <% ${SERVICE_JAR} %> app.jar
ENTRYPOINT ["java", "-Duser.timezone=GMT+08","-jar", "/app.jar" <% ${SERVICE_PARAMS} %> ]docker-compose.yml.tmpl
version: '3'services: <% ${SERVICE_NAME} %>: restart: always image: <% ${SERVICE_IMAGE_NAME} %>:<% ${vTag} %> container_name: <% ${SERVICE_NAME} %> ports: # - <% ${SERVICE_PORT} %>:<% ${SERVICE_PORT} %> 可能多个情况使用sed插入 deploy: resources: limits: memory: <% ${SERVICE_MEMORY} %>convert_param.sh:构造 Dockerfile 中 SERVICE_PARAMS 参数
#!/bin/bashparams=""d=","paramCount=$#for (( i = 1; i <= paramCount; i++ )); do params="$params $d \\"\"${!i}\\"\""doneecho "$params"template.sh:使用环境参数生成文件
#!/bin/shEOF=EOFexec cat <<EOF | shcat <<EOF$(cat $1 | \ sed 's|`|\\`|g' | \ sed 's|\$|\\\$|g' | \ sed "s|${OPEN:-<%}|\`eval echo |g" | \ sed "s|${CLOSE:-%>}|\`|g")$EOFEOF使用
# 查看sh template.sh Dockerfile.tmpl# 使用生成sh template.sh Dockerfile.tmpl > Dockerfile配置 Drone 模板
mvn-deploy.yml:Maven 打包私服模板,工具类等不需要部署的项目
kind: pipeline # 定义对象类型,还有secret和signature两种类型type: docker # 定义流水线类型,还有kubernetes、exec、ssh等类型name: default # 定义流水线名称
steps: # 定义流水线执行步骤,这些步骤将顺序执行 - name: mvn-deploy # 流水线名称 pull: if-not-exists image: {{ .input.buildImage }} # 定义创建容器的Docker镜像 network_mode: host volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置 - name: maven-cache path: /usr/share/maven/ref/repository # 这个需要 Maven settings.xml 中一致 commands: - mvn clean deploy
volumes: # 定义流水线挂载目录,用于共享数据 - name: maven-cache host: path: /data/maven/cache # 主机目录缓存依赖
trigger: event: - pushmvn-build-push-image-run.yaml:Maven 打包部署模板
kind: pipelinetype: dockername: mvn-build-push-image-run-startsteps: - name: mvn-build pull: if-not-exists image: {{ .input.buildImage }} network_mode: host volumes: - name: maven-cache path: /usr/share/maven/ref/repository - name: ci-env path: /app/ci-env commands: # 定义在Docker容器中执行的shell命令 - mvn clean package - rm target/*sources.jar && cp target/*.jar . && cp /app/ci-env/* . - chmod +x template.sh convert_param.sh - export vTag=`ls *.jar | awk -F {{ .input.name }}- '{print $2}' | awk -F .jar '{print $1}'` - export SERVICE_JAR=`ls *.jar` - export SERVICE_PARAMS=`./convert_param.sh {{ range .input.deploy.params }} {{ . }}{{ end }}` - sh template.sh Dockerfile.tmpl > Dockerfile - sh template.sh docker-compose.yml.tmpl > docker-compose.yml - sed -i '5i\{{ range .input.ports }}EXPOSE {{ . }}\n{{ end }}' Dockerfile - sed -i '8i\{{ range .input.ports }} - {{ . }}:{{ . }}\n{{ end }}' docker-compose.yml - echo -n $vTag,latest > .tags environment: FROM_IMAGE: {{ .input.deploy.fromImage }} SERVICE_NAME: {{ .input.name }} SERVICE_MEMORY: {{ .input.memory }} SERVICE_IMAGE_NAME: {{ .input.image.registry }}/{{ .input.image.name }}
83 collapsed lines
- name: push-image pull: if-not-exists image: plugins/docker network_mode: host settings: registry: {{ .input.image.registry }} # if not provided index.docker.io is supposed repo: {{ .input.image.registry }}/{{ .input.image.name }} cache: true username: from_secret: {{ .input.image.docker_username_key }} password: from_secret: {{ .input.image.docker_password_key }}
- name: gitea release image: plugins/gitea-release pull: if-not-exists network_mode: host settings: api_key: from_secret: git_release prerelease: true base_url: https://git.domain.com title: ${DRONE_TAG} files: - ./*.jar - ./*docker-compose.yml - ./*Dockerfile checksum: - md5 - sha1 when: event: tag
- name: scp files image: appleboy/drone-scp pull: if-not-exists settings: host: dev.domain.com # 远程连接地址 port: 22 # 远程连接端口 username: root # 远程连接账号 password: from_secret: dev_password # 从Secret中读取SSH密码 target: {{ .input.workdir }} overwrite: true source: - docker-compose.yml
- name: run-start pull: if-not-exists network_mode: host image: appleboy/drone-ssh # SSH工具镜像 settings: host: dev.domain.com # 远程连接地址 port: 22 # 远程连接端口 username: root # 远程连接账号 password: from_secret: dev_password # 从Secret中读取SSH密码 command_timeout: 5m # 远程执行命令超时时间 envs: - DOCKER_USERNAME - DOCKER_PASSWORD script: - cd {{ .input.workdir }} - echo "$DOCKER_PASSWORD" | docker login {{ .input.image.registry }} -u $DOCKER_USERNAME --password-stdin - docker-compose down && docker-compose pull && docker-compose up -d environment: DOCKER_USERNAME: from_secret: {{ .input.image.docker_username_key }} DOCKER_PASSWORD: from_secret: {{ .input.image.docker_password_key }}
volumes: # 定义流水线挂载目录,用于共享数据 - name: maven-cache host: path: /data/maven/cache - name: ci-env host: path: /data/ci-env
trigger: event: - push - tag编写 .drone.yml 脚本
kind: templateload: mvn-build-push-image-run.yamlname: mvn-build-push-image-rundata: name: drone-demo # 这里需要注意需要和 Jar 包名一致,drone-demo-0.0.1.jar ports: - 8080 # - 9090 memory: 1G workdir: /data/service/drone-demo buildImage: ci/maven:8-jdk
image: registry: harbor.domain.com name: service/drone-demo # docker 用户名密码前缀 需要 secrets 添加 xxx_docker_username docker_username_key: docker_username docker_password_key: docker_password # Dockerfile 配置 deploy: fromImage: eclipse-temurin:8-jdk params: - --spring.profiles.active=dev