From 102608b85c1cf850c2c684415f8dcc0a2dc3314a Mon Sep 17 00:00:00 2001 From: irving Date: Mon, 1 Sep 2025 22:10:44 -0400 Subject: [PATCH] =?UTF-8?q?WIP:=20=E9=87=8D=E6=9E=84Docker=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E6=B5=81=E7=A8=8B=E5=92=8C=E9=83=A8=E7=BD=B2=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新Dockerfile为多阶段构建,提升安全性和构建效率 - 重构docker-compose.yml,添加健康检查和网络配置 - 新增Docker镜像构建和推送脚本 - 修复Maven打包配置,移除不必要的配置项 - 添加.dockerignore文件优化构建上下文 - 删除旧的deploy.sh脚本 - 新增JAR部署和回滚脚本 注意:此为开发中版本,请勿部署到生产环境 --- .dockerignore | 59 +++++++++++++++++++++++ build-docker.sh | 53 +++++++++++++++++++++ deploy-jar.sh | 23 +++++++++ deploy.sh | 11 ----- docker/Dockerfile | 44 ++++++++++++----- docker/README.md | 30 ++++++++++++ docker/docker-compose.yml | 39 ++++++++++++--- play-admin/pom.xml | 11 +---- push-docker.sh | 99 +++++++++++++++++++++++++++++++++++++++ rollback.sh | 12 +++++ 10 files changed, 342 insertions(+), 39 deletions(-) create mode 100644 .dockerignore create mode 100755 build-docker.sh create mode 100755 deploy-jar.sh delete mode 100644 deploy.sh create mode 100644 docker/README.md create mode 100755 push-docker.sh create mode 100755 rollback.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..93449cc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,59 @@ +# Build artifacts and dependencies +target/ +.mvn/ +*.iml +*.ipr +*.iws + +# IDE files +.idea/ +.vscode/ +*.sublime-* +.eclipse +.project +.classpath +.settings/ + +# OS files +.DS_Store +Thumbs.db + +# Version control +.git/ +.gitignore +.gitattributes + +# Documentation and scripts (comment out if needed in container) +README.md +*.md +deploy.sh +rollback.sh +fetch-log.sh + +# Docker files (avoid recursion) +docker/ +Dockerfile* +docker-compose* + +# Logs and temp files +log/ +logs/ +*.log +*.tmp + +# Backup files +backup/ +*.backup +*.bak + +# Environment files +.env +.env.* + +# Test files +**/src/test/ + +# Maven wrapper (we install Maven in container) +.mvn/ +mvnw +mvnw.cmd \ No newline at end of file diff --git a/build-docker.sh b/build-docker.sh new file mode 100755 index 0000000..15d3024 --- /dev/null +++ b/build-docker.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# 构建 Docker 镜像脚本 + +set -e + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo -e "${GREEN}=== 开始构建 PeiPei 后端 Docker 镜像 ===${NC}" + +# 检查是否在正确的目录 +if [ ! -f "docker/Dockerfile" ]; then + echo -e "${RED}错误: 请在项目根目录执行此脚本${NC}" + echo -e "${YELLOW}当前目录: $(pwd)${NC}" + echo -e "${YELLOW}期望目录应包含: docker/Dockerfile${NC}" + exit 1 +fi + +# 获取 UTC+8 时间戳 +TIMESTAMP=$(TZ='Asia/Shanghai' date +"%Y-%m-%d-%Hh-%Mm") +echo -e "${YELLOW}构建时间戳 (UTC+8): ${TIMESTAMP}${NC}" + +# 镜像名称和标签 +IMAGE_NAME="peipei-backend" +VERSION_TAG="${TIMESTAMP}" +LATEST_TAG="latest" + +echo -e "${YELLOW}镜像名称: ${IMAGE_NAME}${NC}" +echo -e "${YELLOW}版本标签: ${VERSION_TAG}${NC}" + +# 构建 Docker 镜像 +echo -e "${GREEN}开始构建镜像...${NC}" +if docker build -f docker/Dockerfile \ + -t "${IMAGE_NAME}:${VERSION_TAG}" \ + -t "${IMAGE_NAME}:${LATEST_TAG}" \ + .; then + + echo -e "${GREEN}✅ Docker 镜像构建成功!${NC}" + echo -e "${GREEN}镜像标签:${NC}" + echo -e " - ${IMAGE_NAME}:${VERSION_TAG}" + echo -e " - ${IMAGE_NAME}:${LATEST_TAG}" + + echo -e "\n${YELLOW}镜像信息:${NC}" + docker images | grep -E "^${IMAGE_NAME}\s" | head -2 + + echo -e "\n${GREEN}下一步: 运行 ./push-docker.sh 推送到私有仓库${NC}" +else + echo -e "${RED}❌ Docker 镜像构建失败!${NC}" + exit 1 +fi diff --git a/deploy-jar.sh b/deploy-jar.sh new file mode 100755 index 0000000..c656131 --- /dev/null +++ b/deploy-jar.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# 发包脚本 +set -e +# 获取当前时间并格式化为指定格式 +current_time=$(date +"%Y-%m-%d %H:%M:%S") +echo "发布开始,当前时间是:$current_time" + +# 构建项目 +echo "开始构建项目..." +mvn clean package -DskipTests +echo "构建完成!" + +# 备份当前的jar文件 +ssh root@122.51.20.105 "source /etc/profile; cd /www/wwwroot/july.hucs.top; if [ -f play-admin-1.0.jar ]; then mv play-admin-1.0.jar play-admin-1.0.jar.backup; fi" +echo "备份完成!" + +scp ./play-admin/target/play-admin-1.0.jar root@122.51.20.105:/www/wwwroot/july.hucs.top +echo "上传成功!" +ssh root@122.51.20.105 "source /etc/profile;cd /www/wwwroot/july.hucs.top;sh start.sh restart" +# 获取当前时间并格式化为指定格式 +current_time=$(date +"%Y-%m-%d %H:%M:%S") + +echo "发布完成,当前时间是:$current_time" \ No newline at end of file diff --git a/deploy.sh b/deploy.sh deleted file mode 100644 index 18e97ba..0000000 --- a/deploy.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# 发包脚本 -set -e -echo "发布开始,当前时间是:$current_time" -#mvn clean install -scp ./play-admin/target/play-admin-1.0.jar root@122.51.20.105:/www/wwwroot/july.hucs.top -ssh root@122.51.20.105 "source /etc/profile;cd /www/wwwroot/july.hucs.top;sh start.sh restart" -# 获取当前时间并格式化为指定格式 -current_time=$(date +"%Y-%m-%d %H:%M:%S") - -echo "发布完成,当前时间是:$current_time" \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index c42e0ef..c16f854 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,16 +1,38 @@ -FROM openjdk:11-jre-slim +# ---------- Build stage ---------- +FROM --platform=$BUILDPLATFORM maven:3.9-eclipse-temurin-11 AS build +WORKDIR /workspace -# 设置工作目录 +# Cache-friendly: copy POMs first +COPY pom.xml . +COPY play-admin/pom.xml play-admin/ +COPY play-common/pom.xml play-common/ +COPY play-generator/pom.xml play-generator/ + +# Warm deps cache +RUN --mount=type=cache,target=/root/.m2 mvn -B -DskipTests dependency:go-offline + +# Add sources +COPY play-admin/src play-admin/src/ +COPY play-common/src play-common/src/ +COPY play-generator/src play-generator/src/ + +# Build only app module (and its deps) +RUN --mount=type=cache,target=/root/.m2 mvn -pl play-admin -am -B -DskipTests -T 1C clean package + +# ---------- Runtime stage (multi-arch) ---------- +FROM eclipse-temurin:11-jre AS runtime +# non-root +RUN groupadd -g 1001 appgroup && useradd -u 1001 -g appgroup -m -s /usr/sbin/nologin appuser WORKDIR /app -# 只复制应用程序JAR包,不复制lib目录 -COPY ./*.jar app.jar +COPY --from=build /workspace/play-admin/target/*.jar /app/app.jar +RUN chown -R appuser:appgroup /app +USER appuser -# 设置环境变量 -ENV APP_NAME=app.jar +ENV JAVA_OPTS="-Xms2g -Xmx2g" \ + SPRING_PROFILES_ACTIVE="test" \ + TZ="Asia/Shanghai" \ + LANG="C.UTF-8" -# 暴露应用端口 -EXPOSE 8080 - -# 设置启动命令 -CMD ["sh", "-c", "java -Dloader.path=./lib/ -Xms2g -Xmx2g -jar $APP_NAME --spring.profiles.active=test"] +EXPOSE 7002 +ENTRYPOINT ["sh","-c","exec java $JAVA_OPTS -jar /app/app.jar --spring.profiles.active=${SPRING_PROFILES_ACTIVE}"] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..0540240 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,30 @@ +# 私有 Docker 仓库使用速查表 +# 仓库地址: https://docker-registry.julyhaven.com +# 用户名: hucs +# 密码: hucsdev + +# 登录 +docker login docker-registry.julyhaven.com -u hucs -p hucsdev + +# 推送镜像 (示例: myapp:1.0.0) +docker tag myapp:1.0.0 docker-registry.julyhaven.com/myteam/myapp:1.0.0 +docker push docker-registry.julyhaven.com/myteam/myapp:1.0.0 + +# 同时推送 latest +docker tag myapp:1.0.0 docker-registry.julyhaven.com/myteam/myapp:latest +docker push docker-registry.julyhaven.com/myteam/myapp:latest + +# 拉取镜像 +docker pull docker-registry.julyhaven.com/myteam/myapp:1.0.0 +docker pull docker-registry.julyhaven.com/myteam/myapp:latest + +# 测试镜像 (hello-world) +docker pull hello-world +docker tag hello-world docker-registry.julyhaven.com/test/hello-world:latest +docker push docker-registry.julyhaven.com/test/hello-world:latest +docker pull docker-registry.julyhaven.com/test/hello-world:latest + +# 注意事项: +# 1. latest 会被覆盖,生产环境请用版本号标签 +# 2. 已支持大镜像推送/拉取,无需额外配置 +# 3. 登录失败时请确认用户名/密码是否正确 diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 452cf9b..3259211 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,12 +1,37 @@ -version: '3' +version: "3.8" services: - spring-boot-app: - build: . - container_name: spring-boot-app + peipei-backend: + image: docker-registry.julyhaven.com/peipei/backend:latest + container_name: peipei-backend ports: - "7003:7002" + environment: + - SPRING_PROFILES_ACTIVE=test + - JAVA_OPTS=-Xms2g -Xmx2g volumes: - - ./lib:/app/lib # 挂载主机的lib目录到容器内的lib目录 - - ./log:/app/log # 挂载日志目录到主机 - restart: always + - ./log:/app/log # Mount log directory to host + restart: unless-stopped + healthcheck: + # Maybe use actuator later + test: + [ + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://localhost:7002/api/health", + ] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + networks: + - peipei-network + +networks: + peipei-network: + driver: bridge +# volumes: +# mysql_data: diff --git a/play-admin/pom.xml b/play-admin/pom.xml index 84b8a8b..abad784 100644 --- a/play-admin/pom.xml +++ b/play-admin/pom.xml @@ -161,19 +161,10 @@ org.springframework.boot spring-boot-maven-plugin 2.7.9 - - ZIP - - - nothing - nothing - - - - repackage + repackage diff --git a/push-docker.sh b/push-docker.sh new file mode 100755 index 0000000..59c972e --- /dev/null +++ b/push-docker.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# 推送 Docker 镜像到私有仓库脚本 + +set -e + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 私有仓库配置 (来自 README.md) +REGISTRY_URL="docker-registry.julyhaven.com" +REGISTRY_USER="hucs" +REGISTRY_PASS="hucsdev" +PROJECT_PATH="peipei/backend" + +echo -e "${GREEN}=== 推送 PeiPei 后端镜像到私有仓库 ===${NC}" + +# 获取 UTC+8 时间戳 +TIMESTAMP=$(TZ='Asia/Shanghai' date +"%Y-%m-%d-%Hh-%Mm") +echo -e "${YELLOW}推送时间戳 (UTC+8): ${TIMESTAMP}${NC}" + +# 本地镜像名称 +LOCAL_IMAGE="peipei-backend" + +# 远程镜像名称和标签 +REMOTE_IMAGE="${REGISTRY_URL}/${PROJECT_PATH}" +VERSION_TAG="${TIMESTAMP}" +LATEST_TAG="latest" + +echo -e "${BLUE}私有仓库地址: ${REGISTRY_URL}${NC}" +echo -e "${BLUE}项目路径: ${PROJECT_PATH}${NC}" +echo -e "${BLUE}远程镜像: ${REMOTE_IMAGE}${NC}" + +# 检查本地镜像是否存在 +if ! docker images | grep -q "${LOCAL_IMAGE}"; then + echo -e "${RED}错误: 本地镜像 ${LOCAL_IMAGE} 不存在${NC}" + echo -e "${YELLOW}请先运行: ./build-docker.sh${NC}" + exit 1 +fi + +# 登录私有仓库 +echo -e "${GREEN}登录私有 Docker 仓库...${NC}" +echo "${REGISTRY_PASS}" | docker login "${REGISTRY_URL}" -u "${REGISTRY_USER}" --password-stdin + +if [ $? -ne 0 ]; then + echo -e "${RED}❌ 登录私有仓库失败!${NC}" + exit 1 +fi + +echo -e "${GREEN}✅ 登录成功!${NC}" + +# 标记镜像 - 版本标签 +echo -e "${GREEN}标记镜像: ${LOCAL_IMAGE}:latest -> ${REMOTE_IMAGE}:${VERSION_TAG}${NC}" +docker tag "${LOCAL_IMAGE}:latest" "${REMOTE_IMAGE}:${VERSION_TAG}" + +# 标记镜像 - latest 标签 +echo -e "${GREEN}标记镜像: ${LOCAL_IMAGE}:latest -> ${REMOTE_IMAGE}:${LATEST_TAG}${NC}" +docker tag "${LOCAL_IMAGE}:latest" "${REMOTE_IMAGE}:${LATEST_TAG}" + +# 推送版本标签 +echo -e "${GREEN}推送版本标签镜像...${NC}" +docker push "${REMOTE_IMAGE}:${VERSION_TAG}" + +if [ $? -ne 0 ]; then + echo -e "${RED}❌ 推送版本标签失败!${NC}" + exit 1 +fi + +# 推送 latest 标签 +echo -e "${GREEN}推送 latest 标签镜像...${NC}" +docker push "${REMOTE_IMAGE}:${LATEST_TAG}" + +if [ $? -ne 0 ]; then + echo -e "${RED}❌ 推送 latest 标签失败!${NC}" + exit 1 +fi + +echo -e "${GREEN}✅ 所有镜像推送成功!${NC}" + +# 显示推送结果 +echo -e "\n${BLUE}推送的镜像:${NC}" +echo -e " 📦 ${REMOTE_IMAGE}:${VERSION_TAG}" +echo -e " 📦 ${REMOTE_IMAGE}:${LATEST_TAG}" + +echo -e "\n${YELLOW}服务器部署命令:${NC}" +echo -e " docker pull ${REMOTE_IMAGE}:${VERSION_TAG}" +echo -e " docker pull ${REMOTE_IMAGE}:${LATEST_TAG}" + +echo -e "\n${YELLOW}更新 docker-compose.yml 中的镜像:${NC}" +echo -e " image: ${REMOTE_IMAGE}:${VERSION_TAG}" + +# 清理本地标记的远程镜像标签 (可选) +echo -e "\n${GREEN}清理本地远程标签...${NC}" +docker rmi "${REMOTE_IMAGE}:${VERSION_TAG}" "${REMOTE_IMAGE}:${LATEST_TAG}" 2>/dev/null || true + +echo -e "\n${GREEN}🚀 推送完成!${NC}" \ No newline at end of file diff --git a/rollback.sh b/rollback.sh new file mode 100755 index 0000000..c5bd181 --- /dev/null +++ b/rollback.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# 快速回滚脚本 +set -e +echo "开始回滚到本地备份版本..." + +# 使用本地备份文件回滚 +scp ./backup/play-admin-1.0-20250830-215753.jar root@122.51.20.105:/www/wwwroot/july.hucs.top/play-admin-1.0.jar +echo "备份文件已上传!" + +# 重启服务 +ssh root@122.51.20.105 "source /etc/profile;cd /www/wwwroot/july.hucs.top;sh start.sh restart" +echo "服务已重启,回滚完成!" \ No newline at end of file