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