部署md
This commit is contained in:
14
docker/schoolNews/.env.example
Normal file
14
docker/schoolNews/.env.example
Normal file
@@ -0,0 +1,14 @@
|
||||
# 数据库配置
|
||||
MYSQL_ROOT_PASSWORD=123456
|
||||
MYSQL_DATABASE=school_news
|
||||
MYSQL_USER=schoolnews
|
||||
MYSQL_PASSWORD=123456
|
||||
MYSQL_PORT=3306
|
||||
|
||||
# Redis配置
|
||||
REDIS_PASSWORD=123456
|
||||
REDIS_PORT=6379
|
||||
|
||||
# 服务端口配置
|
||||
SERV_PORT=8081
|
||||
WEB_PORT=8080
|
||||
61
docker/schoolNews/Dockerfile.base-serv
Normal file
61
docker/schoolNews/Dockerfile.base-serv
Normal file
@@ -0,0 +1,61 @@
|
||||
# ====================================
|
||||
# 后端基础镜像 - Base Serv
|
||||
# 包含:JRE + Python + 系统工具 + 爬虫依赖
|
||||
# 用途:作为后端服务镜像的基础,避免每次都安装依赖
|
||||
# ====================================
|
||||
FROM eclipse-temurin:21-jre
|
||||
|
||||
# 设置环境变量
|
||||
ENV LANG=C.UTF-8 \
|
||||
LC_ALL=C.UTF-8 \
|
||||
TZ=Asia/Shanghai
|
||||
|
||||
# 安装系统依赖和工具
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
# Python环境
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
# 网络和诊断工具
|
||||
netcat-traditional \
|
||||
curl \
|
||||
wget \
|
||||
# MySQL客户端
|
||||
default-mysql-client \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 临时复制requirements.txt用于安装依赖
|
||||
COPY schoolNewsCrawler/requirements.txt /tmp/requirements.txt
|
||||
|
||||
# 安装Python爬虫依赖(一次性安装到基础镜像)
|
||||
RUN echo "========================================" && \
|
||||
echo "安装Python爬虫依赖到基础镜像" && \
|
||||
echo "========================================" && \
|
||||
# 配置pip使用国内镜像源(清华源)
|
||||
python3 -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \
|
||||
python3 -m pip --version && \
|
||||
echo "" && \
|
||||
# Python 3.12 引入了 PEP 668 规范,需要添加 --break-system-packages
|
||||
python3 -m pip install --no-cache-dir --break-system-packages -r /tmp/requirements.txt && \
|
||||
echo "" && \
|
||||
echo "✅ 爬虫依赖安装完成" && \
|
||||
python3 -m pip list | grep -E "(beautifulsoup4|crawl4ai|selenium|pydantic|requests|loguru)" && \
|
||||
# 清理临时文件
|
||||
rm -f /tmp/requirements.txt
|
||||
|
||||
# 创建应用目录结构
|
||||
WORKDIR /app
|
||||
RUN mkdir -p /app/config /app/logs /app/uploads /app/crawler
|
||||
|
||||
# 镜像元数据
|
||||
LABEL maintainer="School News Team" \
|
||||
description="Base image for school-news backend service with Python dependencies" \
|
||||
version="1.0"
|
||||
|
||||
# 暴露端口(文档用途)
|
||||
EXPOSE 8081
|
||||
|
||||
# 默认命令(会被子镜像覆盖)
|
||||
CMD ["echo", "This is base image, please use school-news-serv image"]
|
||||
112
docker/schoolNews/Dockerfile.mysql
Normal file
112
docker/schoolNews/Dockerfile.mysql
Normal file
@@ -0,0 +1,112 @@
|
||||
# 校园新闻管理系统 - MySQL数据库镜像
|
||||
# 基于reInit.sh的数据库初始化方案
|
||||
FROM mysql:8.0
|
||||
|
||||
# 设置环境变量
|
||||
ENV LANG=C.UTF-8 \
|
||||
TZ=Asia/Shanghai
|
||||
|
||||
# 注意:MySQL配置有两种方式
|
||||
# 1. 通过docker-compose.yml的command参数(基础配置)
|
||||
# 2. 通过挂载my.cnf文件(高级配置,可选)
|
||||
# docker-compose.yml中可以取消注释: ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
|
||||
|
||||
# 创建SQL目录
|
||||
RUN mkdir -p /docker-entrypoint-initdb.d /opt/sql
|
||||
|
||||
# 复制所有SQL文件(保持目录结构)
|
||||
COPY schoolNewsServ/.bin/mysql/sql/ /opt/sql/
|
||||
|
||||
# 复制并调整reInit.sh为Docker环境,设置执行权限
|
||||
COPY schoolNewsServ/.bin/mysql/sql/reInit.sh /opt/sql/
|
||||
RUN sed -i 's/DB_HOST="localhost"/DB_HOST="localhost"/' /opt/sql/reInit.sh && \
|
||||
sed -i 's/DB_PORT="3306"/DB_PORT="3306"/' /opt/sql/reInit.sh && \
|
||||
sed -i 's/DB_USER="root"/DB_USER="root"/' /opt/sql/reInit.sh && \
|
||||
sed -i 's/DB_PASSWORD="123456"/DB_PASSWORD="${MYSQL_ROOT_PASSWORD}"/' /opt/sql/reInit.sh && \
|
||||
sed -i 's/DB_NAME="school_news"/DB_NAME="${MYSQL_DATABASE}"/' /opt/sql/reInit.sh && \
|
||||
sed -i 's|LOG_FILE="$SCRIPT_DIR/reInit.log"|LOG_FILE="/tmp/reInit.log"|' /opt/sql/reInit.sh && \
|
||||
chmod +x /opt/sql/reInit.sh && \
|
||||
chmod +x /opt/sql/sensitiveData/importSensitiveWords.sh
|
||||
# 创建Docker初始化适配脚本
|
||||
RUN cat > /docker-entrypoint-initdb.d/01-init-database.sh <<'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "校园新闻管理系统 - 数据库初始化"
|
||||
echo "使用 reInit.sh + Docker配置更新"
|
||||
echo "=========================================="
|
||||
|
||||
# 等待MySQL完全启动
|
||||
echo "等待MySQL启动..."
|
||||
until mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" -e "SELECT 1" >/dev/null 2>&1; do
|
||||
sleep 1
|
||||
done
|
||||
echo "MySQL已就绪"
|
||||
|
||||
# 切换到SQL目录
|
||||
cd /opt/sql
|
||||
|
||||
# 设置环境变量供reInit.sh使用
|
||||
export DB_HOST="localhost"
|
||||
export DB_PORT="3306"
|
||||
export DB_USER="root"
|
||||
export DB_PASSWORD="${MYSQL_ROOT_PASSWORD}"
|
||||
export DB_NAME="${MYSQL_DATABASE}"
|
||||
export MYSQL_PWD="${MYSQL_ROOT_PASSWORD}"
|
||||
|
||||
# Source reInit.sh并调用其初始化函数
|
||||
echo "执行数据库初始化(使用reInit.sh)..."
|
||||
source reInit.sh
|
||||
|
||||
# 调用reInit.sh的核心函数(跳过备份和删除)
|
||||
execute_init_script # 执行initAll.sql
|
||||
import_sensitive_words # 导入敏感词
|
||||
|
||||
# Docker环境特定配置:更新爬虫路径并标记初始化状态
|
||||
echo "更新Docker环境配置..."
|
||||
mysql -uroot "${MYSQL_DATABASE}" <<EOSQL
|
||||
-- 确保初始化标记表存在
|
||||
CREATE TABLE IF NOT EXISTS _db_init_status (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
script_name VARCHAR(255) NOT NULL UNIQUE,
|
||||
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
status VARCHAR(50) DEFAULT 'init'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 确保有一条当前脚本的记录
|
||||
INSERT IGNORE INTO _db_init_status (script_name) VALUES ('01-init-database.sql');
|
||||
|
||||
-- 更新爬虫配置为Docker容器内路径
|
||||
UPDATE tb_sys_config
|
||||
SET config_value = '/usr/bin/python3'
|
||||
WHERE config_key = 'crawler.pythonPath';
|
||||
|
||||
UPDATE tb_sys_config
|
||||
SET config_value = '/app/crawler'
|
||||
WHERE config_key = 'crawler.basePath';
|
||||
|
||||
-- 将初始化状态标记为 success,供 healthcheck 使用
|
||||
UPDATE _db_init_status
|
||||
SET status = 'success'
|
||||
WHERE script_name = '01-init-database.sql';
|
||||
|
||||
SELECT '✅ 数据库初始化完成!' AS message;
|
||||
SELECT '默认用户: admin, 密码: 123456' AS tip;
|
||||
SELECT '爬虫配置已更新为Docker容器路径' AS docker_config;
|
||||
EOSQL
|
||||
|
||||
echo "=========================================="
|
||||
echo "✅ 初始化完成!"
|
||||
echo "=========================================="
|
||||
EOF
|
||||
|
||||
# 设置执行权限
|
||||
RUN chmod +x /docker-entrypoint-initdb.d/01-init-database.sh
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 3306
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=10s --timeout=5s --retries=5 --start-period=30s \
|
||||
CMD mysqladmin ping -h localhost -p${MYSQL_ROOT_PASSWORD} || exit 1
|
||||
30
docker/schoolNews/Dockerfile.serv
Normal file
30
docker/schoolNews/Dockerfile.serv
Normal file
@@ -0,0 +1,30 @@
|
||||
# ====================================
|
||||
# 后端服务镜像 - School News Serv
|
||||
# 基于:school-news-base-serv(已包含Python依赖)
|
||||
# 注意:jar包需要在主机中先编译好
|
||||
# ====================================
|
||||
FROM school-news-base-serv:latest
|
||||
|
||||
# 从主机复制已编译的jar包
|
||||
COPY schoolNewsServ/admin/target/admin-1.0.0.jar /app/app.jar
|
||||
|
||||
# 复制爬虫脚本(基础镜像已安装依赖,这里只需复制脚本)
|
||||
COPY schoolNewsCrawler/ /app/crawler/
|
||||
|
||||
# 复制默认配置文件(作为备份)
|
||||
COPY schoolNewsServ/admin/src/main/resources/application.yml /app/config/application.yml.template
|
||||
COPY schoolNewsServ/admin/src/main/resources/log4j2-spring.xml /app/config/log4j2-spring.xml.template
|
||||
|
||||
# 复制启动脚本
|
||||
COPY schoolNewsServ/docker/start.sh /app/start.sh
|
||||
RUN chmod +x /app/start.sh
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 8081
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost:8081/schoolNewsServ/actuator/health || exit 1
|
||||
|
||||
# 启动应用
|
||||
CMD ["/app/start.sh"]
|
||||
56
docker/schoolNews/Dockerfile.web
Normal file
56
docker/schoolNews/Dockerfile.web
Normal file
@@ -0,0 +1,56 @@
|
||||
# ====================================
|
||||
# 前端服务镜像 - School News Web
|
||||
# 使用Node运行Vite预览服务器
|
||||
# 注意:dist目录需要在主机中先构建好
|
||||
# ====================================
|
||||
FROM node:20-alpine
|
||||
|
||||
# 设置环境变量
|
||||
ENV TZ=Asia/Shanghai \
|
||||
NODE_ENV=production
|
||||
|
||||
# 配置国内镜像源并安装基础工具
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && \
|
||||
apk update && \
|
||||
apk add --no-cache tzdata bash curl && \
|
||||
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 创建应用目录
|
||||
WORKDIR /app
|
||||
|
||||
# 创建必要目录
|
||||
RUN mkdir -p /app/dist /app/config /app/logs
|
||||
|
||||
# 复制package.json和package-lock.json
|
||||
COPY schoolNewsWeb/package*.json ./
|
||||
|
||||
# 安装生产依赖(包括vite用于preview)
|
||||
RUN npm config set registry https://registry.npmmirror.com && \
|
||||
npm ci --only=production && \
|
||||
npm install -g vite
|
||||
|
||||
# 从主机复制已构建的dist目录
|
||||
COPY schoolNewsWeb/dist/ /app/dist/
|
||||
|
||||
# 复制配置文件模板(可整个替换)
|
||||
COPY schoolNewsWeb/public/app-config.js /app/config/app-config.js.template
|
||||
|
||||
# 确保dist中有默认配置文件
|
||||
RUN if [ ! -f /app/dist/app-config.js ]; then \
|
||||
cp /app/config/app-config.js.template /app/dist/app-config.js; \
|
||||
fi
|
||||
|
||||
# 复制启动脚本
|
||||
COPY schoolNewsWeb/docker/start.sh /app/start.sh
|
||||
RUN chmod +x /app/start.sh
|
||||
|
||||
# 暴露端口(Vite preview默认4173)
|
||||
EXPOSE 4173
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \
|
||||
CMD curl -f http://localhost:4173/ || exit 1
|
||||
|
||||
# 启动应用
|
||||
CMD ["/app/start.sh"]
|
||||
184
docker/schoolNews/config/application.yml
Normal file
184
docker/schoolNews/config/application.yml
Normal file
@@ -0,0 +1,184 @@
|
||||
server:
|
||||
port: 8081
|
||||
servlet:
|
||||
context-path: /schoolNewsServ
|
||||
encoding:
|
||||
charset: UTF-8
|
||||
enabled: true
|
||||
force: true
|
||||
spring:
|
||||
application:
|
||||
name: school-news-admin
|
||||
|
||||
# 数据源配置 - Docker环境
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://${MYSQL_HOST:mysql}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:school_news}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: ${MYSQL_USER:root}
|
||||
password: ${MYSQL_PASSWORD:123456}
|
||||
hikari:
|
||||
maximum-pool-size: 30
|
||||
minimum-idle: 10
|
||||
connection-timeout: 30000
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
|
||||
# Redis配置 - Docker环境
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:redis}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: ${REDIS_PASSWORD:123456}
|
||||
database: 0
|
||||
timeout: 10000
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 50
|
||||
max-wait: 3000
|
||||
max-idle: 20
|
||||
min-idle: 5
|
||||
shutdown-timeout: 100ms
|
||||
|
||||
# 邮件配置
|
||||
mail:
|
||||
host: smtp.qq.com
|
||||
port: 587
|
||||
username: 3223905473@qq.com
|
||||
password: xmdmxvtjumxocicc
|
||||
default-encoding: UTF-8
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
auth: true
|
||||
starttls:
|
||||
enable: true
|
||||
required: true
|
||||
|
||||
# 短信服务配置
|
||||
sms:
|
||||
enabled: true
|
||||
provider: aliyun
|
||||
access-key-id: LTAI5t68do3qVXx5Rufugt3X
|
||||
access-key-secret: 2vD9ToIff49Vph4JQXsn0Cy8nXQfzA
|
||||
sign-name: 星洋智慧
|
||||
template-code: SMS_491985030
|
||||
region-id: cn-hangzhou
|
||||
endpoint: dysmsapi.aliyuncs.com
|
||||
|
||||
# 认证配置
|
||||
school-news:
|
||||
auth:
|
||||
jwt-secret: schoolNewsSecretKeyForJWT2025SecureEnough
|
||||
jwt-expiration: 86400
|
||||
max-login-attempts: 5
|
||||
lockout-duration: 30
|
||||
white-list:
|
||||
- "/auth/login"
|
||||
- "/auth/logout"
|
||||
- "/auth/register"
|
||||
- "/auth/captcha"
|
||||
- "/auth/send-sms-code"
|
||||
- "/auth/send-email-code"
|
||||
- "/auth/health"
|
||||
- "/actuator/**"
|
||||
- "/swagger-ui/**"
|
||||
- "/v3/api-docs/**"
|
||||
- "/favicon.ico"
|
||||
- "/error"
|
||||
- "/public/**"
|
||||
- "/static/**"
|
||||
- "/file/download/**"
|
||||
- "/ai/chat/stream/**"
|
||||
|
||||
# 爬虫配置 - Docker环境
|
||||
crawler:
|
||||
# 容器内Python路径
|
||||
pythonPath: /usr/bin/python3
|
||||
# 容器内爬虫脚本根目录
|
||||
basePath: /app/crawler
|
||||
|
||||
crontab:
|
||||
items:
|
||||
- name: 人民日报新闻爬取
|
||||
methods:
|
||||
- name: 关键字搜索爬取
|
||||
clazz: newsCrewerTask
|
||||
excuete_method: execute
|
||||
path: crawler/RmrbSearch.py
|
||||
params:
|
||||
- name: query
|
||||
description: 搜索关键字
|
||||
type: String
|
||||
value: ""
|
||||
- name: total
|
||||
description: 总新闻数量
|
||||
type: Integer
|
||||
value: 10
|
||||
- name: 排行榜爬取
|
||||
clazz: newsCrewerTask
|
||||
excuete_method: execute
|
||||
path: crawler/RmrbHotPoint.py
|
||||
- name: 往日精彩头条爬取
|
||||
clazz: newsCrewerTask
|
||||
excuete_method: execute
|
||||
path: crawler/RmrbTrending.py
|
||||
params:
|
||||
- name: startDate
|
||||
description: 开始日期
|
||||
type: String
|
||||
value: ""
|
||||
- name: endDate
|
||||
description: 结束日期
|
||||
type: String
|
||||
value: ""
|
||||
- name: yesterday
|
||||
description: 是否是昨天
|
||||
type: Boolean
|
||||
value: true
|
||||
|
||||
# dify
|
||||
dify:
|
||||
knowledgeApiKey: dataset-nupqKP4LONpzdXmGthIrbjeJ
|
||||
|
||||
# 文件存储配置
|
||||
file:
|
||||
storage:
|
||||
storages:
|
||||
- type: local
|
||||
enabled: true
|
||||
base-path: /app/uploads
|
||||
|
||||
# MyBatis Plus配置
|
||||
mybatis-plus:
|
||||
type-aliases-package: org.xyzh.common.dto
|
||||
mapper-locations: classpath*:mapper/*.xml
|
||||
global-config:
|
||||
db-config:
|
||||
logic-delete-field: deleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
insert-strategy: not_null
|
||||
update-strategy: not_null
|
||||
select-strategy: not_empty
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
cache-enabled: true
|
||||
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
config: classpath:log4j2-spring.xml
|
||||
charset:
|
||||
console: UTF-8
|
||||
file: UTF-8
|
||||
|
||||
# 管理端点配置
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,env
|
||||
endpoint:
|
||||
health:
|
||||
show-details: when-authorized
|
||||
debug: false
|
||||
208
docker/schoolNews/config/log4j2-spring.xml
Normal file
208
docker/schoolNews/config/log4j2-spring.xml
Normal file
@@ -0,0 +1,208 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
校园新闻管理系统 - Admin模块日志配置
|
||||
-->
|
||||
<configuration status="WARN" monitorInterval="30">
|
||||
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
|
||||
|
||||
<!--变量配置-->
|
||||
<Properties>
|
||||
<!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
|
||||
<!-- %logger{36} 表示 Logger 名字最长36个字符 -->
|
||||
<property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
|
||||
<!-- 定义日志存储的路径 -->
|
||||
<property name="FILE_PATH" value="./logs" />
|
||||
<!-- Admin模块日志文件名 -->
|
||||
<property name="FILE_NAME" value="school-news-admin" />
|
||||
<!-- 设置系统属性 -->
|
||||
<property name="file.encoding" value="UTF-8" />
|
||||
<property name="console.encoding" value="UTF-8" />
|
||||
<property name="stdout.encoding" value="UTF-8" />
|
||||
<property name="stderr.encoding" value="UTF-8" />
|
||||
</Properties>
|
||||
|
||||
<appenders>
|
||||
|
||||
<console name="Console" target="SYSTEM_OUT">
|
||||
<!--输出日志的格式-->
|
||||
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
|
||||
<!--控制台输出debug及以上级别的信息-->
|
||||
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
</console>
|
||||
|
||||
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
|
||||
<File name="Filelog" fileName="${FILE_PATH}/${FILE_NAME}-test.log" append="false">
|
||||
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
|
||||
</File>
|
||||
|
||||
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
|
||||
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/${FILE_NAME}-info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
|
||||
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
|
||||
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
|
||||
<Policies>
|
||||
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
|
||||
<TimeBasedTriggeringPolicy interval="1"/>
|
||||
<SizeBasedTriggeringPolicy size="10MB"/>
|
||||
</Policies>
|
||||
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
|
||||
<DefaultRolloverStrategy max="15"/>
|
||||
</RollingFile>
|
||||
|
||||
<!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
|
||||
<RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/${FILE_NAME}-warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
|
||||
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
|
||||
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
|
||||
<Policies>
|
||||
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
|
||||
<TimeBasedTriggeringPolicy interval="1"/>
|
||||
<SizeBasedTriggeringPolicy size="10MB"/>
|
||||
</Policies>
|
||||
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
|
||||
<DefaultRolloverStrategy max="15"/>
|
||||
</RollingFile>
|
||||
|
||||
<!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
|
||||
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/${FILE_NAME}-error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
|
||||
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
|
||||
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
|
||||
<Policies>
|
||||
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
|
||||
<TimeBasedTriggeringPolicy interval="1"/>
|
||||
<SizeBasedTriggeringPolicy size="10MB"/>
|
||||
</Policies>
|
||||
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
|
||||
<DefaultRolloverStrategy max="15"/>
|
||||
</RollingFile>
|
||||
|
||||
<!-- 数据库日志Appender - 异步写入DEBUG级别及以上的日志到数据库 -->
|
||||
<DatabaseAppender name="DatabaseAppender" ignoreExceptions="false">
|
||||
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
</DatabaseAppender>
|
||||
|
||||
</appenders>
|
||||
|
||||
<!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
|
||||
<!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
|
||||
<loggers>
|
||||
|
||||
<!--过滤掉spring的一些无用的DEBUG信息-->
|
||||
<logger name="org.mybatis" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
</logger>
|
||||
<!--监控系统信息-->
|
||||
<!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,不会在 父Logger 的appender里输出。-->
|
||||
<Logger name="org.springframework" level="info" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Logger>
|
||||
|
||||
<!-- MyBatis Mapper 日志配置 - 打印SQL -->
|
||||
<Logger name="org.xyzh.achievement.mapper" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Logger>
|
||||
<Logger name="org.xyzh.ai.mapper" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Logger>
|
||||
<Logger name="org.xyzh.system.mapper" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Logger>
|
||||
<Logger name="org.xyzh.news.mapper" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Logger>
|
||||
<Logger name="org.xyzh.study.mapper" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Logger>
|
||||
<Logger name="org.xyzh.crontab.mapper" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Logger>
|
||||
<Logger name="org.xyzh.message.mapper" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Logger>
|
||||
<!-- 项目包日志配置 - Auth模块 -->
|
||||
<Logger name="org.xyzh.auth" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
<AppenderRef ref="Filelog"/>
|
||||
<AppenderRef ref="RollingFileInfo"/>
|
||||
<AppenderRef ref="RollingFileWarn"/>
|
||||
<AppenderRef ref="RollingFileError"/>
|
||||
<AppenderRef ref="DatabaseAppender"/>
|
||||
</Logger>
|
||||
|
||||
<!-- 项目包日志配置 - System模块 -->
|
||||
<Logger name="org.xyzh.system" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
<AppenderRef ref="Filelog"/>
|
||||
<AppenderRef ref="RollingFileInfo"/>
|
||||
<AppenderRef ref="RollingFileWarn"/>
|
||||
<AppenderRef ref="RollingFileError"/>
|
||||
<AppenderRef ref="DatabaseAppender"/>
|
||||
</Logger>
|
||||
|
||||
<!-- 项目包日志配置 - News模块 -->
|
||||
<Logger name="org.xyzh.news" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
<AppenderRef ref="Filelog"/>
|
||||
<AppenderRef ref="RollingFileInfo"/>
|
||||
<AppenderRef ref="RollingFileWarn"/>
|
||||
<AppenderRef ref="RollingFileError"/>
|
||||
<AppenderRef ref="DatabaseAppender"/>
|
||||
</Logger>
|
||||
|
||||
<!-- 项目包日志配置 - Common模块 -->
|
||||
<Logger name="org.xyzh.common" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
<AppenderRef ref="Filelog"/>
|
||||
<AppenderRef ref="RollingFileInfo"/>
|
||||
<AppenderRef ref="RollingFileWarn"/>
|
||||
<AppenderRef ref="RollingFileError"/>
|
||||
<AppenderRef ref="DatabaseAppender"/>
|
||||
</Logger>
|
||||
|
||||
<!-- 项目包日志配置 - Achievement模块 -->
|
||||
<Logger name="org.xyzh.achievement" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
<AppenderRef ref="Filelog"/>
|
||||
<AppenderRef ref="RollingFileInfo"/>
|
||||
<AppenderRef ref="RollingFileWarn"/>
|
||||
<AppenderRef ref="RollingFileError"/>
|
||||
<AppenderRef ref="DatabaseAppender"/>
|
||||
</Logger>
|
||||
|
||||
<Logger name="org.xyzh.crontab" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
<AppenderRef ref="Filelog"/>
|
||||
<AppenderRef ref="RollingFileInfo"/>
|
||||
<AppenderRef ref="RollingFileWarn"/>
|
||||
<AppenderRef ref="RollingFileError"/>
|
||||
<AppenderRef ref="DatabaseAppender"/>
|
||||
</Logger>
|
||||
<Logger name="org.xyzh.message" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
<AppenderRef ref="Filelog"/>
|
||||
<AppenderRef ref="RollingFileInfo"/>
|
||||
<AppenderRef ref="RollingFileWarn"/>
|
||||
<AppenderRef ref="RollingFileError"/>
|
||||
<AppenderRef ref="DatabaseAppender"/>
|
||||
</Logger>
|
||||
<Logger name="org.xyzh.sensitive" level="debug" additivity="false">
|
||||
<AppenderRef ref="Console"/>
|
||||
<AppenderRef ref="Filelog"/>
|
||||
<AppenderRef ref="RollingFileInfo"/>
|
||||
<AppenderRef ref="RollingFileWarn"/>
|
||||
<AppenderRef ref="RollingFileError"/>
|
||||
<AppenderRef ref="DatabaseAppender"/>
|
||||
</Logger>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="Console"/>
|
||||
<appender-ref ref="Filelog"/>
|
||||
<appender-ref ref="RollingFileInfo"/>
|
||||
<appender-ref ref="RollingFileWarn"/>
|
||||
<appender-ref ref="RollingFileError"/>
|
||||
<appender-ref ref="DatabaseAppender"/>
|
||||
</root>
|
||||
</loggers>
|
||||
|
||||
</configuration>
|
||||
74
docker/schoolNews/config/web-app-config.js
Normal file
74
docker/schoolNews/config/web-app-config.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* 前端应用配置文件
|
||||
*
|
||||
* 此文件用于Docker部署时的配置外挂
|
||||
* 挂载方式:docker-compose.yml 中配置
|
||||
* volumes:
|
||||
* - ./config/web-app-config.js:/app/config/app-config.js
|
||||
*
|
||||
* 修改步骤:
|
||||
* 1. 编辑此文件
|
||||
* 2. 重启容器:docker-compose restart school-news-web
|
||||
* 3. 刷新浏览器即可生效
|
||||
*
|
||||
* 注意:此文件结构必须与 schoolNewsWeb/public/app-config.js 保持一致
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
window.APP_RUNTIME_CONFIG = {
|
||||
// 环境标识
|
||||
env: 'production',
|
||||
|
||||
// API 配置
|
||||
api: {
|
||||
baseUrl: '/schoolNewsServ', // API基础路径
|
||||
timeout: 30000 // 请求超时时间(毫秒)
|
||||
},
|
||||
|
||||
// 应用基础路径
|
||||
baseUrl: '/schoolNewsWeb/',
|
||||
|
||||
// 文件配置
|
||||
file: {
|
||||
downloadUrl: '/schoolNewsServ/file/download/',
|
||||
uploadUrl: '/schoolNewsServ/file/upload/',
|
||||
maxSize: {
|
||||
image: 5, // MB
|
||||
video: 100, // MB
|
||||
document: 10 // MB
|
||||
},
|
||||
acceptTypes: {
|
||||
image: 'image/*',
|
||||
video: 'video/*',
|
||||
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||
}
|
||||
},
|
||||
|
||||
// Token 配置
|
||||
token: {
|
||||
key: 'token',
|
||||
refreshThreshold: 300000 // 5分钟(毫秒)
|
||||
},
|
||||
|
||||
// 公共路径
|
||||
publicImgPath: '/schoolNewsWeb/img',
|
||||
publicWebPath: '/schoolNewsWeb',
|
||||
|
||||
// 功能开关(可自由扩展)
|
||||
features: {
|
||||
enableDebug: false, // 是否启用调试模式
|
||||
enableMockData: false // 是否启用Mock数据
|
||||
}
|
||||
};
|
||||
|
||||
// 配置加载完成标记
|
||||
window.__CONFIG_LOADED__ = true;
|
||||
|
||||
// 控制台输出配置信息
|
||||
if (console && console.log) {
|
||||
console.log('%c[配置]%c Docker配置已加载', 'color: green; font-weight: bold', 'color: inherit');
|
||||
console.log('[配置] 环境:', window.APP_RUNTIME_CONFIG.env);
|
||||
console.log('[配置] API地址:', window.APP_RUNTIME_CONFIG.api.baseUrl);
|
||||
}
|
||||
})();
|
||||
57
docker/schoolNews/config/web/index.ts
Normal file
57
docker/schoolNews/config/web/index.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @description 应用配置 - Docker生产环境
|
||||
* @author yslg
|
||||
* @since 2025-10-18
|
||||
*/
|
||||
|
||||
// 生产环境配置
|
||||
const isDev = false;
|
||||
|
||||
// API 基础路径 - Docker环境使用相对路径
|
||||
export const API_BASE_URL = '/schoolNewsServ';
|
||||
|
||||
// 文件下载路径
|
||||
export const FILE_DOWNLOAD_URL = `${API_BASE_URL}/file/download/`;
|
||||
|
||||
// 应用配置
|
||||
export const APP_CONFIG = {
|
||||
// 应用标题
|
||||
title: '校园新闻管理系统',
|
||||
|
||||
// 基础路径
|
||||
baseUrl: '/schoolNewsWeb/',
|
||||
|
||||
// API 配置
|
||||
api: {
|
||||
baseUrl: API_BASE_URL,
|
||||
timeout: 30000
|
||||
},
|
||||
|
||||
// 文件配置
|
||||
file: {
|
||||
downloadUrl: FILE_DOWNLOAD_URL,
|
||||
uploadUrl: `${API_BASE_URL}/file/upload`,
|
||||
maxSize: {
|
||||
image: 5, // MB
|
||||
video: 100, // MB
|
||||
document: 10 // MB
|
||||
},
|
||||
acceptTypes: {
|
||||
image: 'image/*',
|
||||
video: 'video/*',
|
||||
document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
|
||||
}
|
||||
},
|
||||
|
||||
// Token 配置
|
||||
token: {
|
||||
key: 'token',
|
||||
refreshThreshold: 5 * 60 * 1000 // 提前5分钟刷新
|
||||
}
|
||||
};
|
||||
|
||||
// 公共资源路径 - Docker环境
|
||||
export const PUBLIC_IMG_PATH = '/schoolNewsWeb/img';
|
||||
export const PUBLIC_WEB_PATH = '/schoolNewsWeb';
|
||||
|
||||
export default APP_CONFIG;
|
||||
81
docker/schoolNews/config/web/vite.config.js
Normal file
81
docker/schoolNews/config/web/vite.config.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { VitePWA } from 'vite-plugin-pwa'
|
||||
import { resolve } from 'path'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
VitePWA({
|
||||
registerType: 'autoUpdate',
|
||||
workbox: {
|
||||
cleanupOutdatedCaches: true,
|
||||
skipWaiting: true,
|
||||
clientsClaim: true
|
||||
}
|
||||
})
|
||||
],
|
||||
|
||||
// 基础路径
|
||||
base: '/schoolNewsWeb/',
|
||||
file: {
|
||||
downloadUrl: "http://school-news-serv:8081/schoolNewsServ/file/download/"
|
||||
},
|
||||
|
||||
// 输出目录
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
assetsDir: 'static',
|
||||
sourcemap: false,
|
||||
chunkSizeWarningLimit: 1500,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
'vue-vendor': ['vue', 'vue-router', 'vuex'],
|
||||
'element-plus': ['element-plus']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 路径别名
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve(__dirname, 'src')
|
||||
},
|
||||
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
|
||||
},
|
||||
|
||||
// 环境变量
|
||||
define: {
|
||||
'process.env.BASE_URL': JSON.stringify('/schoolNewsWeb/'),
|
||||
'process.env.VITE_API_BASE_URL': JSON.stringify('/api'),
|
||||
'process.env.VITE_APP_TITLE': JSON.stringify('校园新闻管理系统')
|
||||
},
|
||||
|
||||
// 开发服务器配置(生产环境无效)
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 8080,
|
||||
open: '/schoolNewsWeb/',
|
||||
|
||||
// 代理配置
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://school-news-serv:8081/schoolNewsServ',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// CSS 配置
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
259
docker/schoolNews/docker-compose.yml
Normal file
259
docker/schoolNews/docker-compose.yml
Normal file
@@ -0,0 +1,259 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# MySQL数据库
|
||||
mysql:
|
||||
image: school-news-mysql:latest
|
||||
container_name: school-news-mysql
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-123456}
|
||||
MYSQL_DATABASE: ${MYSQL_DATABASE:-school_news}
|
||||
MYSQL_USER: ${MYSQL_USER:-schoolnews}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-123456}
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "${MYSQL_PORT:-3307}:3306"
|
||||
volumes:
|
||||
# 数据持久化(命名卷)
|
||||
- mysql-data:/var/lib/mysql
|
||||
# 自定义配置文件(可选,取消注释以启用)
|
||||
# 如需自定义MySQL配置,取消下面的注释并修改mysql/my.cnf
|
||||
# - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
|
||||
command:
|
||||
- --character-set-server=utf8mb4
|
||||
- --collation-server=utf8mb4_unicode_ci
|
||||
- --default-authentication-plugin=mysql_native_password
|
||||
- --max_connections=1000
|
||||
- --max_allowed_packet=64M
|
||||
- --local-infile=1
|
||||
networks:
|
||||
- school-news-network
|
||||
healthcheck:
|
||||
# 只有当 MySQL 可访问且敏感词表中至少有一条 deny 记录时,才认为 healthy
|
||||
test: ["CMD-SHELL", "mysql -uroot -p${MYSQL_ROOT_PASSWORD:-123456} -D ${MYSQL_DATABASE:-school_news} -e \"SELECT 'ok' FROM _db_init_status WHERE script_name='01-init-database.sql' AND status='success' LIMIT 1;\" 2>/dev/null | grep -q ok"]
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
start_period: 60s
|
||||
|
||||
# Redis缓存
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: school-news-redis
|
||||
restart: always
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "${REDIS_PORT:-6379}:6379"
|
||||
volumes:
|
||||
# 数据持久化(命名卷)
|
||||
- redis-data:/data
|
||||
# Redis配置文件(命名卷)
|
||||
- redis-config:/usr/local/etc/redis
|
||||
command: redis-server /usr/local/etc/redis/redis.conf --requirepass ${REDIS_PASSWORD:-123456}
|
||||
networks:
|
||||
- school-news-network
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
|
||||
# 后端服务
|
||||
school-news-serv:
|
||||
image: school-news-serv:latest
|
||||
container_name: school-news-serv
|
||||
restart: always
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
# 数据库配置
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
MYSQL_DATABASE: ${MYSQL_DATABASE:-school_news}
|
||||
MYSQL_USER: ${MYSQL_USER:-root}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-123456}
|
||||
# Redis配置
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
REDIS_PASSWORD: ${REDIS_PASSWORD:-123456}
|
||||
# JVM配置
|
||||
JAVA_OPTS: "-Xms512m -Xmx1g -XX:+UseG1GC"
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "${SERV_PORT:-8081}:8081"
|
||||
volumes:
|
||||
# 配置文件(命名卷)
|
||||
- serv-config:/app/config
|
||||
# 日志目录(命名卷)
|
||||
- serv-logs:/app/logs
|
||||
# 上传文件目录(命名卷)
|
||||
- serv-uploads:/app/uploads
|
||||
# 爬虫脚本目录(默认不挂载,保留在镜像内)
|
||||
# 注意:挂载会覆盖镜像内容,如需运行时更新爬虫脚本可取消注释
|
||||
- serv-crawler:/app/crawler
|
||||
networks:
|
||||
- school-news-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8081/schoolNewsServ/actuator/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
|
||||
# 前端服务(Node + Vite Preview)
|
||||
school-news-web:
|
||||
image: school-news-web:latest
|
||||
container_name: school-news-web
|
||||
restart: always
|
||||
depends_on:
|
||||
- school-news-serv
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
NODE_ENV: production
|
||||
# 不直接暴露端口,通过nginx反向代理访问
|
||||
expose:
|
||||
- "4173"
|
||||
volumes:
|
||||
# 运行时配置文件(命名卷)
|
||||
- web-config:/app/config
|
||||
# 日志目录(命名卷)
|
||||
- web-logs:/app/logs
|
||||
networks:
|
||||
- school-news-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:4173/"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
|
||||
# Nginx反向代理
|
||||
nginx:
|
||||
image: nginx:alpine # 直接使用官方镜像,无需自定义构建
|
||||
container_name: school-news-nginx
|
||||
restart: always
|
||||
depends_on:
|
||||
- school-news-web
|
||||
- school-news-serv
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "${NGINX_PORT:-80}:80"
|
||||
volumes:
|
||||
# 仅挂载自定义 Nginx 主配置文件
|
||||
- ./volumes/nginx/config/nginx.conf:/etc/nginx/nginx.conf
|
||||
# 仅挂载站点配置目录(conf.d),保留镜像内的 mime.types 等其他文件
|
||||
- nginx-conf-d:/etc/nginx/conf.d:ro
|
||||
# 日志目录(命名卷)
|
||||
- nginx-logs:/var/log/nginx
|
||||
networks:
|
||||
- school-news-network
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
networks:
|
||||
school-news-network:
|
||||
driver: bridge
|
||||
|
||||
# 命名卷定义(数据存储在当前目录下的volumes/子目录)
|
||||
# 使用前请先运行初始化脚本:./init-volumes.sh 或 init-volumes.bat
|
||||
volumes:
|
||||
# ===== MySQL =====
|
||||
mysql-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/mysql/data
|
||||
|
||||
# ===== Redis =====
|
||||
redis-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/redis/data
|
||||
|
||||
redis-config:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/redis/config
|
||||
|
||||
# ===== 后端服务 =====
|
||||
serv-config:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/serv/config
|
||||
|
||||
serv-logs:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/serv/logs
|
||||
|
||||
serv-uploads:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/serv/uploads
|
||||
|
||||
# 爬虫脚本目录(可选,默认不启用)
|
||||
# 注意:启用后会覆盖镜像内的爬虫脚本,需先复制镜像内容到volumes/serv/crawler
|
||||
serv-crawler:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/serv/crawler
|
||||
|
||||
# ===== 前端服务 =====
|
||||
web-config:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/web/config
|
||||
|
||||
web-logs:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/web/logs
|
||||
|
||||
# ===== Nginx =====
|
||||
nginx-conf-file:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/nginx/config/nginx.conf
|
||||
|
||||
nginx-conf-d:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/nginx/config/conf.d
|
||||
|
||||
nginx-logs:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ./volumes/nginx/logs
|
||||
29
docker/schoolNews/init-db/01-init-database.sql
Normal file
29
docker/schoolNews/init-db/01-init-database.sql
Normal file
@@ -0,0 +1,29 @@
|
||||
-- ========================================
|
||||
-- 校园新闻管理系统数据库初始化脚本
|
||||
--
|
||||
-- 注意:
|
||||
-- 1. 本脚本仅在数据库首次创建时执行
|
||||
-- 2. 如果数据库已存在,请手动执行或使用02-check-init.sh
|
||||
-- ========================================
|
||||
|
||||
-- 创建数据库(如果不存在)
|
||||
-- 创建数据库,使用utf8mb4字符集
|
||||
CREATE DATABASE IF NOT EXISTS `school_news` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- 使用数据库
|
||||
USE `school_news`;
|
||||
|
||||
-- 检查表是否已存在,避免重复初始化
|
||||
-- 创建一个标记表记录初始化状态
|
||||
CREATE TABLE IF NOT EXISTS _db_init_status (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
script_name VARCHAR(255) NOT NULL UNIQUE,
|
||||
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
status VARCHAR(50) DEFAULT 'init'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 记录初始化标记
|
||||
INSERT IGNORE INTO _db_init_status (script_name) VALUES ('01-init-database.sql');
|
||||
|
||||
-- 提示信息
|
||||
SELECT CONCAT('数据库 school_news 初始化完成。请将您的表结构脚本放在 02-create-tables.sql 中') AS message;
|
||||
334
docker/schoolNews/init-db/README.md
Normal file
334
docker/schoolNews/init-db/README.md
Normal file
@@ -0,0 +1,334 @@
|
||||
# 数据库初始化脚本说明
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本目录包含数据库初始化脚本,用于Docker容器首次启动时自动初始化数据库。
|
||||
|
||||
**基于**: `schoolNewsServ/.bin/mysql/sql/reInit.sh` 的实现逻辑
|
||||
|
||||
## 📂 脚本文件
|
||||
|
||||
| 文件 | 说明 | 状态 |
|
||||
|------|------|------|
|
||||
| `01-init-database.sql` | 创建数据库和初始化标记表 | ✅ 已就绪 |
|
||||
| `02-create-tables.sql` | 创建所有业务表(50+张) | ⚠️ 需准备 |
|
||||
| `03-init-data.sql` | 导入初始数据(用户、菜单等) | ⚠️ 需准备 |
|
||||
| `prepare-sql.sh` | 自动准备脚本 | ✅ 已就绪 |
|
||||
| `数据库初始化指南.md` | 详细说明文档 | ✅ 已就绪 |
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 方式1: 使用自动脚本(推荐)
|
||||
|
||||
```bash
|
||||
cd docker/init-db
|
||||
chmod +x prepare-sql.sh
|
||||
./prepare-sql.sh
|
||||
```
|
||||
|
||||
脚本会自动:
|
||||
1. ✅ 从 `schoolNewsServ/.bin/mysql/sql/` 读取所有SQL文件
|
||||
2. ✅ 合并所有 `createTable*.sql` 到 `02-create-tables.sql`
|
||||
3. ✅ 合并所有 `init*.sql` 到 `03-init-data.sql`
|
||||
4. ✅ 添加Docker环境特定配置(爬虫路径等)
|
||||
5. ✅ 生成统计信息
|
||||
|
||||
### 方式2: 手动准备
|
||||
|
||||
参见 [数据库初始化指南.md](数据库初始化指南.md)
|
||||
|
||||
## 📊 脚本执行顺序
|
||||
|
||||
MySQL容器会按照文件名的字母顺序自动执行此目录下的`.sql`文件:
|
||||
|
||||
```
|
||||
容器启动
|
||||
↓
|
||||
01-init-database.sql
|
||||
├─ 创建数据库 school_news
|
||||
└─ 创建初始化标记表 _db_init_status
|
||||
↓
|
||||
02-create-tables.sql
|
||||
├─ 创建用户模块表(3+张)
|
||||
├─ 创建权限模块表(10+张)
|
||||
├─ 创建资源模块表(5+张)
|
||||
├─ 创建学习模块表(8+张)
|
||||
├─ 创建AI模块表(5+张)
|
||||
├─ 创建系统模块表(5+张)
|
||||
├─ 创建成就模块表(5+张)
|
||||
├─ 创建定时任务模块表(3+张)
|
||||
├─ 创建消息模块表(3+张)
|
||||
└─ 创建敏感词模块表(1+张)
|
||||
↓
|
||||
03-init-data.sql
|
||||
├─ 导入菜单和权限数据
|
||||
├─ 导入默认用户和角色
|
||||
├─ 导入系统配置
|
||||
└─ 导入Docker环境配置(爬虫路径)
|
||||
↓
|
||||
数据库就绪 ✓
|
||||
```
|
||||
|
||||
## 🎯 初始化特性
|
||||
|
||||
### 幂等性设计
|
||||
|
||||
所有脚本支持重复执行,不会导致错误:
|
||||
|
||||
```sql
|
||||
-- 表创建使用IF NOT EXISTS
|
||||
CREATE TABLE IF NOT EXISTS tb_user (...);
|
||||
|
||||
-- 数据插入使用INSERT IGNORE
|
||||
INSERT IGNORE INTO tb_sys_config VALUES (...);
|
||||
|
||||
-- 使用_db_init_status表跟踪执行状态
|
||||
INSERT IGNORE INTO _db_init_status (script_name) VALUES ('02-create-tables.sql');
|
||||
```
|
||||
|
||||
### 避免重复初始化
|
||||
|
||||
系统使用 `_db_init_status` 表来跟踪已执行的脚本:
|
||||
|
||||
```bash
|
||||
# 查看已执行的脚本
|
||||
docker exec school-news-mysql mysql -uroot -p123456 school_news -e \
|
||||
"SELECT * FROM _db_init_status ORDER BY executed_at;"
|
||||
```
|
||||
|
||||
## 🗄️ 数据库结构
|
||||
|
||||
### 模块组成
|
||||
|
||||
| 模块 | 表数量 | 说明 |
|
||||
|------|--------|------|
|
||||
| 用户管理 | 3+ | 用户、部门、角色 |
|
||||
| 权限管理 | 10+ | 菜单、权限、角色权限映射 |
|
||||
| 资源管理 | 5+ | 资源、标签、分类、评论 |
|
||||
| 课程管理 | 3+ | 课程、章节、课件 |
|
||||
| 学习管理 | 5+ | 学习记录、笔记、错题 |
|
||||
| 个人中心 | 3+ | 收藏、历史、个人信息 |
|
||||
| AI智能体 | 5+ | AI对话、知识库 |
|
||||
| 系统配置 | 5+ | 配置、日志、文件管理 |
|
||||
| 成就系统 | 5+ | 成就、徽章、等级 |
|
||||
| 定时任务 | 3+ | 任务、执行记录、元数据 |
|
||||
| 消息通知 | 3+ | 消息、通知、模板 |
|
||||
| 敏感词 | 1+ | 敏感词过滤 |
|
||||
|
||||
**总计**: 50+ 张表
|
||||
|
||||
### 默认数据
|
||||
|
||||
#### 默认用户
|
||||
- **用户名**: admin
|
||||
- **密码**: admin123
|
||||
- **角色**: 管理员(拥有所有权限)
|
||||
|
||||
#### 系统配置
|
||||
- `crawler.pythonPath`: /usr/bin/python3
|
||||
- `crawler.basePath`: /app/crawler
|
||||
|
||||
## 🔄 重新初始化
|
||||
|
||||
### 完全重新初始化(会删除所有数据)
|
||||
|
||||
```bash
|
||||
# 停止并删除容器和数据卷
|
||||
cd docker
|
||||
docker-compose down -v
|
||||
|
||||
# 重新启动
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 只重置初始化标记
|
||||
|
||||
```bash
|
||||
# 清空标记表,下次重启时重新执行脚本
|
||||
docker exec school-news-mysql mysql -uroot -p123456 -e \
|
||||
"TRUNCATE TABLE school_news._db_init_status;"
|
||||
|
||||
# 重启MySQL容器
|
||||
docker-compose restart mysql
|
||||
```
|
||||
|
||||
## 🧪 验证初始化
|
||||
|
||||
### 1. 查看初始化日志
|
||||
|
||||
```bash
|
||||
docker logs school-news-mysql 2>&1 | grep -i "init\|sql"
|
||||
```
|
||||
|
||||
### 2. 检查数据库和表
|
||||
|
||||
```bash
|
||||
# 检查数据库
|
||||
docker exec school-news-mysql mysql -uroot -p123456 -e "SHOW DATABASES;"
|
||||
|
||||
# 检查表数量
|
||||
docker exec school-news-mysql mysql -uroot -p123456 school_news -e \
|
||||
"SELECT COUNT(*) AS table_count FROM information_schema.tables WHERE table_schema='school_news';"
|
||||
|
||||
# 查看所有表
|
||||
docker exec school-news-mysql mysql -uroot -p123456 school_news -e "SHOW TABLES;"
|
||||
```
|
||||
|
||||
### 3. 验证默认数据
|
||||
|
||||
```bash
|
||||
# 检查默认用户
|
||||
docker exec school-news-mysql mysql -uroot -p123456 school_news -e \
|
||||
"SELECT username, nickname, status FROM tb_sys_user WHERE username='admin';"
|
||||
|
||||
# 检查系统配置
|
||||
docker exec school-news-mysql mysql -uroot -p123456 school_news -e \
|
||||
"SELECT config_key, config_value FROM tb_sys_config WHERE config_key LIKE 'crawler.%';"
|
||||
|
||||
# 检查菜单数量
|
||||
docker exec school-news-mysql mysql -uroot -p123456 school_news -e \
|
||||
"SELECT COUNT(*) AS menu_count FROM tb_sys_menu;"
|
||||
```
|
||||
|
||||
### 4. 检查初始化状态
|
||||
|
||||
```bash
|
||||
docker exec school-news-mysql mysql -uroot -p123456 school_news -e \
|
||||
"SELECT script_name, executed_at, status FROM _db_init_status ORDER BY executed_at;"
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 1. SOURCE语句不支持
|
||||
|
||||
Docker的mysql镜像**不支持** `SOURCE` 语句,需要将所有SQL合并到一个文件:
|
||||
|
||||
```sql
|
||||
-- ❌ 不支持
|
||||
SOURCE createTableUser.sql;
|
||||
|
||||
-- ✅ 需要合并
|
||||
-- 将createTableUser.sql的内容直接复制过来
|
||||
CREATE TABLE tb_user (...);
|
||||
```
|
||||
|
||||
### 2. 文件执行顺序
|
||||
|
||||
文件按字母顺序执行,命名规范:
|
||||
|
||||
```
|
||||
01-xxx.sql (最先执行)
|
||||
02-xxx.sql (其次执行)
|
||||
03-xxx.sql (最后执行)
|
||||
04-xxx.sql (可选:迁移脚本)
|
||||
```
|
||||
|
||||
### 3. 字符集配置
|
||||
|
||||
确保使用UTF8MB4字符集:
|
||||
|
||||
```sql
|
||||
CREATE TABLE tb_xxx (
|
||||
...
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
```
|
||||
|
||||
### 4. 安全性
|
||||
|
||||
生产环境必须:
|
||||
- ✅ 修改默认密码
|
||||
- ✅ 使用强密码策略
|
||||
- ✅ 限制数据库访问权限
|
||||
- ✅ 定期备份数据
|
||||
|
||||
## 🗂️ 数据持久化
|
||||
|
||||
数据库数据持久化在Docker数据卷中:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
mysql-data:
|
||||
driver: local
|
||||
```
|
||||
|
||||
### 查看和管理数据卷
|
||||
|
||||
```bash
|
||||
# 查看所有数据卷
|
||||
docker volume ls
|
||||
|
||||
# 查看数据卷详情
|
||||
docker volume inspect docker_mysql-data
|
||||
|
||||
# 备份数据卷
|
||||
docker run --rm -v docker_mysql-data:/data -v $(pwd):/backup \
|
||||
alpine tar czf /backup/mysql-backup.tar.gz /data
|
||||
|
||||
# 恢复数据卷
|
||||
docker run --rm -v docker_mysql-data:/data -v $(pwd):/backup \
|
||||
alpine tar xzf /backup/mysql-backup.tar.gz -C /
|
||||
```
|
||||
|
||||
## 🐛 故障排查
|
||||
|
||||
### 问题1: 脚本未执行
|
||||
|
||||
**症状**: 数据库创建了但没有表
|
||||
|
||||
**排查**:
|
||||
```bash
|
||||
# 查看MySQL日志
|
||||
docker logs school-news-mysql
|
||||
|
||||
# 检查SQL文件
|
||||
ls -l docker/init-db/*.sql
|
||||
```
|
||||
|
||||
**解决**:
|
||||
- 确保SQL文件有读权限
|
||||
- 检查SQL语法是否正确
|
||||
|
||||
### 问题2: 初始化失败
|
||||
|
||||
**症状**: 容器启动失败或反复重启
|
||||
|
||||
**排查**:
|
||||
```bash
|
||||
# 查看错误日志
|
||||
docker logs school-news-mysql 2>&1 | grep -i error
|
||||
|
||||
# 进入容器检查
|
||||
docker exec -it school-news-mysql bash
|
||||
```
|
||||
|
||||
**解决**:
|
||||
- 检查SQL语法错误
|
||||
- 确保表之间的依赖关系正确
|
||||
- 验证数据格式是否正确
|
||||
|
||||
### 问题3: 重复执行导致错误
|
||||
|
||||
**解决**: 使用幂等性设计
|
||||
- 使用 `CREATE TABLE IF NOT EXISTS`
|
||||
- 使用 `INSERT IGNORE`
|
||||
- 使用 `_db_init_status` 表跟踪
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [数据库初始化指南](数据库初始化指南.md) - 详细的准备和使用说明
|
||||
- [reInit.sh](../../schoolNewsServ/.bin/mysql/sql/reInit.sh) - 原始初始化脚本
|
||||
- [Docker README](../README.md) - Docker部署文档
|
||||
|
||||
## 💡 最佳实践
|
||||
|
||||
1. ✅ **自动化** - 使用 `prepare-sql.sh` 自动准备SQL文件
|
||||
2. ✅ **幂等性** - 确保脚本可以重复执行
|
||||
3. ✅ **版本控制** - SQL文件纳入Git管理(注意敏感信息)
|
||||
4. ✅ **文档同步** - 表结构变更同步更新SQL文件
|
||||
5. ✅ **定期备份** - 重要数据定期备份
|
||||
6. ✅ **测试验证** - 在测试环境充分验证后再部署生产
|
||||
|
||||
---
|
||||
|
||||
**更新时间**: 2025-11-24
|
||||
**基于**: schoolNewsServ/.bin/mysql/sql/reInit.sh v1.1.0
|
||||
65
docker/schoolNews/init-volumes.bat
Normal file
65
docker/schoolNews/init-volumes.bat
Normal file
@@ -0,0 +1,65 @@
|
||||
@echo off
|
||||
REM ============================================
|
||||
REM 初始化 Docker Volumes 目录 (Windows)
|
||||
REM ============================================
|
||||
|
||||
echo ========================================
|
||||
echo 初始化 Docker Volumes 目录
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
REM 创建所有卷目录(分层结构)
|
||||
echo 创建数据目录...
|
||||
if not exist "volumes" mkdir "volumes"
|
||||
if not exist "volumes\mysql\data" mkdir "volumes\mysql\data"
|
||||
if not exist "volumes\redis\data" mkdir "volumes\redis\data"
|
||||
if not exist "volumes\redis\config" mkdir "volumes\redis\config"
|
||||
if not exist "volumes\serv\config" mkdir "volumes\serv\config"
|
||||
if not exist "volumes\serv\logs" mkdir "volumes\serv\logs"
|
||||
if not exist "volumes\serv\uploads" mkdir "volumes\serv\uploads"
|
||||
REM if not exist "volumes\serv\crawler" mkdir "volumes\serv\crawler" REM 可选,如需运行时更新爬虫可取消注释
|
||||
if not exist "volumes\web\config" mkdir "volumes\web\config"
|
||||
if not exist "volumes\web\logs" mkdir "volumes\web\logs"
|
||||
if not exist "volumes\nginx\config" mkdir "volumes\nginx\config"
|
||||
if not exist "volumes\nginx\logs" mkdir "volumes\nginx\logs"
|
||||
|
||||
REM 复制配置文件模板
|
||||
echo 复制配置文件模板...
|
||||
if exist "redis\redis.conf" (copy /Y "redis\redis.conf" "volumes\redis\config\" >nul) else (echo ⚠️ redis.conf 不存在)
|
||||
if exist "config\application.yml" (copy /Y "config\application.yml" "volumes\serv\config\" >nul) else (echo ⚠️ application.yml 不存在)
|
||||
if exist "config\log4j2-spring.xml" (copy /Y "config\log4j2-spring.xml" "volumes\serv\config\" >nul) else (echo ⚠️ log4j2-spring.xml 不存在)
|
||||
if exist "config\web-app-config.js" (copy /Y "config\web-app-config.js" "volumes\web\config\app-config.js" >nul) else (echo ⚠️ web-app-config.js 不存在)
|
||||
if exist "nginx\nginx.conf" (xcopy /E /Y "nginx\*" "volumes\nginx\config\" >nul) else (echo ⚠️ nginx配置 不存在)
|
||||
REM if exist "..\schoolNewsCrawler" (xcopy /E /Y "..\schoolNewsCrawler\*" "volumes\serv\crawler\" >nul) else (echo ⚠️ 爬虫脚本 不存在) REM 可选
|
||||
|
||||
echo.
|
||||
echo ✅ 目录创建完成:
|
||||
dir /b volumes
|
||||
echo.
|
||||
|
||||
echo ========================================
|
||||
echo 目录结构说明:
|
||||
echo ========================================
|
||||
echo volumes\
|
||||
echo ├── mysql\
|
||||
echo │ └── data\ - MySQL数据库数据
|
||||
echo ├── redis\
|
||||
echo │ ├── data\ - Redis缓存数据
|
||||
echo │ └── config\ - Redis配置文件
|
||||
echo ├── serv\
|
||||
echo │ ├── config\ - 后端配置文件
|
||||
echo │ ├── logs\ - 后端服务日志
|
||||
echo │ ├── uploads\ - 后端上传文件
|
||||
echo │ └── crawler\ - 爬虫脚本(可选,默认在镜像内)
|
||||
echo ├── web\
|
||||
echo │ ├── config\ - 前端配置文件
|
||||
echo │ └── logs\ - 前端服务日志
|
||||
echo └── nginx\
|
||||
echo ├── config\ - Nginx配置文件
|
||||
echo └── logs\ - Nginx访问日志
|
||||
echo.
|
||||
echo ✅ 初始化完成!现在可以启动服务了:
|
||||
echo docker-compose up -d
|
||||
echo ========================================
|
||||
|
||||
pause
|
||||
70
docker/schoolNews/init-volumes.sh
Normal file
70
docker/schoolNews/init-volumes.sh
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
|
||||
##############################################
|
||||
# 初始化 Docker Volumes 目录
|
||||
# 用途:创建所有命名卷需要的本地目录
|
||||
##############################################
|
||||
|
||||
echo "========================================"
|
||||
echo "初始化 Docker Volumes 目录"
|
||||
echo "========================================"
|
||||
|
||||
# 获取脚本所在目录
|
||||
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
VOLUMES_DIR="${SCRIPT_DIR}/volumes"
|
||||
|
||||
echo "创建目录: ${VOLUMES_DIR}"
|
||||
|
||||
# 创建所有卷目录(分层结构)
|
||||
echo "创建数据目录..."
|
||||
mkdir -p "${VOLUMES_DIR}/mysql/data"
|
||||
mkdir -p "${VOLUMES_DIR}/redis/data"
|
||||
mkdir -p "${VOLUMES_DIR}/redis/config"
|
||||
mkdir -p "${VOLUMES_DIR}/serv/config"
|
||||
mkdir -p "${VOLUMES_DIR}/serv/logs"
|
||||
mkdir -p "${VOLUMES_DIR}/serv/uploads"
|
||||
mkdir -p "${VOLUMES_DIR}/serv/crawler" # 可选,如需运行时更新爬虫可取消注释
|
||||
mkdir -p "${VOLUMES_DIR}/web/config"
|
||||
mkdir -p "${VOLUMES_DIR}/web/logs"
|
||||
mkdir -p "${VOLUMES_DIR}/nginx/config"
|
||||
mkdir -p "${VOLUMES_DIR}/nginx/logs"
|
||||
|
||||
# 复制配置文件模板
|
||||
echo "复制配置文件模板..."
|
||||
[ -f "${SCRIPT_DIR}/redis/redis.conf" ] && cp "${SCRIPT_DIR}/redis/redis.conf" "${VOLUMES_DIR}/redis/config/" || echo " ⚠️ redis.conf 不存在"
|
||||
[ -f "${SCRIPT_DIR}/mysql/my.cnf" ] && cp "${SCRIPT_DIR}/mysql/my.cnf" "${VOLUMES_DIR}/mysql/" || echo " ⚠️ my.cnf 不存在"
|
||||
[ -f "${SCRIPT_DIR}/config/application.yml" ] && cp "${SCRIPT_DIR}/config/application.yml" "${VOLUMES_DIR}/serv/config/" || echo " ⚠️ application.yml 不存在"
|
||||
[ -f "${SCRIPT_DIR}/config/log4j2-spring.xml" ] && cp "${SCRIPT_DIR}/config/log4j2-spring.xml" "${VOLUMES_DIR}/serv/config/" || echo " ⚠️ log4j2-spring.xml 不存在"
|
||||
[ -f "${SCRIPT_DIR}/config/web-app-config.js" ] && cp "${SCRIPT_DIR}/config/web-app-config.js" "${VOLUMES_DIR}/web/config/app-config.js" || echo " ⚠️ web-app-config.js 不存在"
|
||||
[ -f "${SCRIPT_DIR}/nginx/nginx.conf" ] && cp -r "${SCRIPT_DIR}/nginx"/* "${VOLUMES_DIR}/nginx/config/" || echo " ⚠️ nginx配置 不存在"
|
||||
[ -d "${SCRIPT_DIR}/crawler/" ] && cp -r "${SCRIPT_DIR}/crawler"/* "${VOLUMES_DIR}/serv/crawler/" || echo " ⚠️ 爬虫脚本 不存在"
|
||||
|
||||
echo ""
|
||||
echo "✅ 目录创建完成:"
|
||||
tree -L 2 "${VOLUMES_DIR}" 2>/dev/null || ls -la "${VOLUMES_DIR}"
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo "目录结构说明:"
|
||||
echo "========================================"
|
||||
echo "volumes/"
|
||||
echo "├── mysql/"
|
||||
echo "│ └── data/ - MySQL数据库数据"
|
||||
echo "├── redis/"
|
||||
echo "│ ├── data/ - Redis缓存数据"
|
||||
echo "│ └── config/ - Redis配置文件"
|
||||
echo "├── serv/"
|
||||
echo "│ ├── config/ - 后端配置文件"
|
||||
echo "│ ├── logs/ - 后端服务日志"
|
||||
echo "│ ├── uploads/ - 后端上传文件"
|
||||
echo "│ └── crawler/ - 爬虫脚本(可选,默认在镜像内)"
|
||||
echo "├── web/"
|
||||
echo "│ ├── config/ - 前端配置文件"
|
||||
echo "│ └── logs/ - 前端服务日志"
|
||||
echo "└── nginx/"
|
||||
echo " ├── config/ - Nginx配置文件"
|
||||
echo " └── logs/ - Nginx访问日志"
|
||||
echo ""
|
||||
echo "✅ 初始化完成!现在可以启动服务了:"
|
||||
echo " docker-compose up -d"
|
||||
echo "========================================"
|
||||
40
docker/schoolNews/mysql/my.cnf
Normal file
40
docker/schoolNews/mysql/my.cnf
Normal file
@@ -0,0 +1,40 @@
|
||||
[mysqld]
|
||||
# 基本设置
|
||||
character-set-server=utf8mb4
|
||||
collation-server=utf8mb4_unicode_ci
|
||||
default-authentication-plugin=mysql_native_password
|
||||
|
||||
# 连接设置
|
||||
max_connections=1000
|
||||
max_connect_errors=100
|
||||
max_allowed_packet=64M
|
||||
|
||||
# 性能优化
|
||||
innodb_buffer_pool_size=256M
|
||||
innodb_log_file_size=64M
|
||||
innodb_flush_log_at_trx_commit=2
|
||||
innodb_flush_method=O_DIRECT
|
||||
|
||||
# 查询缓存
|
||||
query_cache_type=0
|
||||
query_cache_size=0
|
||||
|
||||
# 慢查询日志
|
||||
slow_query_log=1
|
||||
slow_query_log_file=/var/log/mysql/slow.log
|
||||
long_query_time=2
|
||||
|
||||
# 二进制日志
|
||||
log_bin=mysql-bin
|
||||
binlog_format=ROW
|
||||
expire_logs_days=7
|
||||
max_binlog_size=100M
|
||||
|
||||
# 时区设置
|
||||
default-time-zone='+08:00'
|
||||
|
||||
[mysql]
|
||||
default-character-set=utf8mb4
|
||||
|
||||
[client]
|
||||
default-character-set=utf8mb4
|
||||
74
docker/schoolNews/nginx/conf.d/default.conf
Normal file
74
docker/schoolNews/nginx/conf.d/default.conf
Normal file
@@ -0,0 +1,74 @@
|
||||
# ====================================
|
||||
# 校园新闻系统 - Nginx反向代理配置
|
||||
# ====================================
|
||||
|
||||
# 上游服务定义
|
||||
upstream web_backend {
|
||||
server school-news-web:4173;
|
||||
}
|
||||
|
||||
upstream api_backend {
|
||||
server school-news-serv:8081;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
# 日志配置
|
||||
access_log /var/log/nginx/school-news-access.log;
|
||||
error_log /var/log/nginx/school-news-error.log;
|
||||
|
||||
# 客户端上传大小限制
|
||||
client_max_body_size 100M;
|
||||
|
||||
# 根路径重定向到前端
|
||||
location = / {
|
||||
return 301 /schoolNewsWeb/;
|
||||
}
|
||||
|
||||
# 前端应用代理(Node Vite Preview)
|
||||
location /schoolNewsWeb/ {
|
||||
proxy_pass http://web_backend/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# WebSocket支持(如果需要HMR)
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# 后端API代理
|
||||
location /schoolNewsServ/ {
|
||||
proxy_pass http://api_backend/schoolNewsServ/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
# 缓冲设置
|
||||
proxy_buffering on;
|
||||
proxy_buffer_size 4k;
|
||||
proxy_buffers 8 4k;
|
||||
}
|
||||
|
||||
# 错误页面
|
||||
error_page 404 /schoolNewsWeb/;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
32
docker/schoolNews/nginx/nginx.conf
Normal file
32
docker/schoolNews/nginx/nginx.conf
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
pid /run/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
#gzip on;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
41
docker/schoolNews/redis/redis.conf
Normal file
41
docker/schoolNews/redis/redis.conf
Normal file
@@ -0,0 +1,41 @@
|
||||
# Redis配置文件 - Docker环境
|
||||
|
||||
# 网络配置
|
||||
bind 0.0.0.0
|
||||
protected-mode yes
|
||||
port 6379
|
||||
|
||||
# 持久化配置
|
||||
# RDB快照
|
||||
save 900 1
|
||||
save 300 10
|
||||
save 60 10000
|
||||
stop-writes-on-bgsave-error yes
|
||||
rdbcompression yes
|
||||
rdbchecksum yes
|
||||
dbfilename dump.rdb
|
||||
dir /data
|
||||
|
||||
# AOF持久化
|
||||
appendonly yes
|
||||
appendfilename "appendonly.aof"
|
||||
appendfsync everysec
|
||||
no-appendfsync-on-rewrite no
|
||||
auto-aof-rewrite-percentage 100
|
||||
auto-aof-rewrite-min-size 64mb
|
||||
|
||||
# 内存管理
|
||||
maxmemory 512mb
|
||||
maxmemory-policy allkeys-lru
|
||||
|
||||
# 日志
|
||||
loglevel notice
|
||||
logfile ""
|
||||
|
||||
# 客户端
|
||||
maxclients 10000
|
||||
timeout 300
|
||||
|
||||
# 慢查询日志
|
||||
slowlog-log-slower-than 10000
|
||||
slowlog-max-len 128
|
||||
Reference in New Issue
Block a user