feat: docker build with maven cache and docker profile

- Add Dockerfile for in-container maven build (offline mode)
- Add application-docker.yml for docker environment
- Add logback-docker.xml for docker logging
- Update docker-compose.yml: use strong passwords, docker profile
- Add full database backup before rebuild
- Add .m2-repo to gitignore

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
2026-01-16 17:12:26 +08:00
co-authored by factory-droid[bot]
parent 8c8161adb3
commit 4ec6ac68ca
6 changed files with 4771 additions and 10 deletions
+1
View File
@@ -43,3 +43,4 @@ nul
# MinIO 运行时数据
minio_data/
minio_data/
.m2-repo/
+24 -5
View File
@@ -1,14 +1,33 @@
FROM eclipse-temurin:17-jre-alpine
# 构建阶段
FROM maven:3.9-eclipse-temurin-17 AS builder
RUN apk add --no-cache curl
WORKDIR /build
# 复制本地 Maven 仓库(已缓存的依赖)
COPY .m2-repo /root/.m2/repository
# 复制源码
COPY pom.xml .
COPY src ./src
# 离线编译
RUN mvn clean package -DskipTests -B -o
# 运行阶段
FROM eclipse-temurin:17-jre-jammy
LABEL maintainer="JohnSion"
LABEL description="武术比赛管理系统后端服务"
WORKDIR /app
COPY target/blade-api.jar /app/blade-api.jar
COPY --from=builder /build/target/blade-api.jar /app/blade-api.jar
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 CMD curl -f http://localhost:8123/actuator/health || exit 1
EXPOSE 8123
HEALTHCHECK --interval=30s --timeout=3s --start-period=90s --retries=3 CMD curl -f http://localhost:8123/actuator/health || exit 1
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
ENV SPRING_PROFILE=dev
ENV SPRING_PROFILE="docker"
CMD ["sh", "-c", "java ${JAVA_OPTS} -jar /app/blade-api.jar --spring.profiles.active=${SPRING_PROFILE}"]
File diff suppressed because one or more lines are too long
+5 -5
View File
@@ -27,13 +27,13 @@ services:
image: redis:7-alpine
container_name: martial-redis
restart: always
command: redis-server --requirepass 123456
command: redis-server --requirepass Martial@2026#Secure!Pwd
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "123456", "ping"]
test: ["CMD", "redis-cli", "-a", "Martial@2026#Secure!Pwd", "ping"]
interval: 10s
timeout: 5s
retries: 5
@@ -86,18 +86,18 @@ services:
martial-api:
build:
context: .
dockerfile: Dockerfile.quick
dockerfile: Dockerfile
container_name: martial-api
restart: always
environment:
SPRING_PROFILE: dev
SPRING_PROFILE: docker
JAVA_OPTS: "-Xms512m -Xmx1024m -XX:+UseG1GC"
SPRING_DATASOURCE_URL: jdbc:mysql://martial-mysql:3306/martial_db?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: Martial@2026#Secure!Pwd
SPRING_DATA_REDIS_HOST: redis
SPRING_DATA_REDIS_PORT: 6379
SPRING_DATA_REDIS_PASSWORD: 123456
SPRING_DATA_REDIS_PASSWORD: Martial@2026#Secure!Pwd
ports:
- "8123:8123"
depends_on:
+47
View File
@@ -0,0 +1,47 @@
# =====================================================
# Docker 环境配置
# 用于 docker-compose 部署时使用
# 启动参数: --spring.profiles.active=docker
# =====================================================
spring:
data:
redis:
host: redis
port: 6379
password: Martial@2026#Secure!Pwd
database: 0
ssl:
enabled: false
datasource:
url: jdbc:mysql://martial-mysql:3306/martial_db?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
username: root
password: Martial@2026#Secure!Pwd
# OSS 配置 (MinIO)
oss:
enabled: true
name: minio
tenant-mode: true
endpoint: http://minio:9000
transform-endpoint: https://martial-oss.aitisai.com
access-key: JohnSion
secret-key: v!*BTket4oagDdw
bucket-name: assets
# 第三方登陆
social:
enabled: true
domain: https://martial-api.aitisai.com
# Blade 配置
blade:
lock:
enabled: false
address: redis://redis:6379
password: Martial@2026#Secure!Pwd
file:
remote-mode: true
upload-domain: https://martial-oss.aitisai.com
remote-path: /data/assets
+113
View File
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">
<!-- 自定义参数监听 -->
<contextListener class="org.springblade.core.log.listener.LoggerStartupListener"/>
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<if condition='property("ELK_MODE").toUpperCase().contains("TRUE")'>
<then>
<!-- 推送日志至elk -->
<appender name="STDOUT_LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${DESTINATION}</destination>
<!-- 日志输出编码 -->
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"traceId": "%X{traceId}",
"requestId": "%X{requestId}",
"accountId": "%X{accountId}",
"tenantId": "%X{tenantId}",
"logLevel": "%level",
"serviceName": "${springAppName:-SpringApp}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"line":"%L",
"message": "%message"
}
</pattern>
</pattern>
<mdc/>
<stackTrace/>
</providers>
</encoder>
</appender>
</then>
</if>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="${STDOUT_APPENDER}"/>
</root>
<logger name="net.sf.ehcache" level="INFO"/>
<logger name="druid.sql" level="INFO"/>
<!-- MyBatis log configure -->
<logger name="com.apache.ibatis" level="INFO"/>
<logger name="org.mybatis.spring" level="INFO"/>
<logger name="java.sql.Connection" level="INFO"/>
<logger name="java.sql.Statement" level="INFO"/>
<logger name="java.sql.PreparedStatement" level="INFO"/>
<!-- 减少部分debug日志 -->
<logger name="druid.sql" level="INFO"/>
<logger name="org.apache.shiro" level="INFO"/>
<logger name="org.mybatis.spring" level="INFO"/>
<logger name="org.springframework" level="INFO"/>
<logger name="org.springframework.context" level="WARN"/>
<logger name="org.springframework.beans" level="WARN"/>
<logger name="com.baomidou.mybatisplus" level="INFO"/>
<logger name="org.apache.ibatis.io" level="INFO"/>
<logger name="org.apache.velocity" level="INFO"/>
<logger name="org.eclipse.jetty" level="INFO"/>
<logger name="io.undertow" level="INFO"/>
<logger name="org.xnio.nio" level="INFO"/>
<logger name="org.thymeleaf" level="INFO"/>
<logger name="springfox.documentation" level="INFO"/>
<logger name="org.hibernate.validator" level="INFO"/>
<logger name="com.netflix.loadbalancer" level="INFO"/>
<logger name="com.netflix.hystrix" level="INFO"/>
<logger name="com.netflix.zuul" level="INFO"/>
<logger name="de.codecentric" level="INFO"/>
<!-- cache INFO -->
<logger name="net.sf.ehcache" level="INFO"/>
<logger name="org.springframework.cache" level="INFO"/>
<!-- cloud -->
<logger name="org.apache.http" level="INFO"/>
<logger name="com.netflix.discovery" level="INFO"/>
<logger name="com.netflix.eureka" level="INFO"/>
<!-- 业务日志 -->
<Logger name="org.springblade" level="INFO"/>
<Logger name="org.springblade.core.tenant" level="INFO"/>
<Logger name="org.springblade.core.version" level="INFO"/>
<!-- 减少nacos日志 -->
<logger name="com.alibaba.nacos" level="ERROR"/>
</configuration>