AstrNest 安装与配置指南
面向运维/开发的落地说明:列出必须填的环境变量、文件路径、初始化脚本与部署要点。建议按顺序完成,最后再启动 Docker Compose 或本地进程。
1. 快速清单
| 项目 | 必填内容 | 修改文件/位置 |
|---|---|---|
| 数据库连接 | 主机、端口、库名、账号、密码 | .env / backend/src/main/resources/application.yml / docker-compose.yml (mysql、backend 服务环境变量) / backend/db/init.sql |
| 管理员账号 | 用户名、初始密码、昵称、邮箱 | .env + backend/db/init.sql (INSERT INTO users ...) |
| 上传路径 | 本地磁盘目录、对外访问前缀 | .env (ASTRNEST_STORAGE_ROOT/ASTRNEST_STORAGE_PUBLIC),必要时在 Nginx 中反代 /upload/** 到后端 |
| 站点域名 | 前端站点地址、图片直链域名、API 域名 | .env (PUBLIC_SITE_URL/PUBLIC_ASSET_URL/BACKEND_API_PUBLIC_URL),后台"系统配置"里的 asset_domain |
| 后端地址 | 前端访问的 API 地址 | frontend/.env 或编译期传入 VITE_API_BASE_URL |
| 图片访问地址 | 未配置 asset_domain 时默认 https://{当前域名}/upload/{yyyy}/{MM}/文件 | Nginx/网关 /upload/** 反向代理到 backend:8080,或在 .env 中给 ASTRNEST_ASSET_DOMAIN/VITE_PUBLIC_ASSET_BASE 明确域名 |
| 邮件服务 | SMTP Host/Port/账号/授权码/发件人 | 启动后在后台「设置 > 邮件服务」里填写,或在 backend/db/init.sql 的 chenxi_mail_config 段改占位值 |
| AI 内容审核 | 腾讯云 SecretId/SecretKey、Region、Bucket | .env 中的 ASTRNEST_AI_TENCENT_* 或在后台「系统配置 > AI 智能审核」配置 |
| 视频缩略图 | FFmpeg 路径、截图偏移、质量 | .env 中的 ASTRNEST_VIDEO_THUMBNAIL_* 或后台配置 |
1.1 文件路径速查
| 文件路径 | 需确认/修改的参数 | 适用场景 |
|---|---|---|
.env(根目录) | MYSQL_*、ASTRNEST_DB_*、ASTRNEST_STORAGE_*、ASTRNEST_ADMIN_*、PUBLIC_SITE_URL、PUBLIC_ASSET_URL、BACKEND_API_PUBLIC_URL、ASTRNEST_ASSET_DOMAIN、VITE_API_BASE_URL、VITE_PUBLIC_ASSET_BASE、VITE_SITE_NAME、SMTP_*、ASTRNEST_AI_TENCENT_*、ASTRNEST_VIDEO_THUMBNAIL_* | Docker Compose 及本地 shell 的统一入口,docker compose --env-file .env up -d 会读取这些值 |
docker-compose.yml | services.mysql.environment.*(数据库名/账号/密码)、services.backend.environment.*(后端连接串、管理员、存储路径)、services.frontend.environment.*(前端访问后端/图片地址) | 如需为某环境写死参数,可直接在对应服务的 environment 块覆盖 .env |
backend/src/main/resources/application.yml | spring.datasource.*、astrnest.storage.*、astrnest.admin.* | 裸机运行或 IDE 调试时的兜底配置,所有键均可被环境变量覆盖 |
backend/db/init.sql | CREATE DATABASE/USER、GRANT、INSERT INTO users、INSERT INTO chenxi_mail_config、UPDATE system_config | 初始化数据库结构、管理员信息与 SMTP 占位;部署前请替换库名/账号、管理员邮箱与密码哈希 |
backend/db/init_windows.sql | 同上,但移除了 DELIMITER 等 Windows/Navicat 不兼容语法 | Windows 环境下推荐使用 |
frontend/.env.development / .env.production / .env.example | VITE_API_BASE_URL、VITE_PUBLIC_ASSET_BASE、VITE_SITE_NAME | 控制前端向哪台后端发起请求以及生成图片直链的域名/路径 |
frontend/src/services/http.js | axios.create({ baseURL: ... }) | 若不依赖 .env,可在此处直接写死后端请求地址 |
📦 建议做法:先复制
.env.example为.env,确认每一项都贴合目标环境,再依次调整application.yml、init.sql、frontend/.env.production。
2. 环境变量样例 (.env)
cp .env.example .env
# 编辑 .env 后生效在 docker compose / shell 中.env 同时被 docker-compose.yml、backend/src/main/resources/application.yml 以及前端构建脚本读取,务必在启动前替换掉所有占位值:
- 先写对数据库主机、端口、库名、账号、密码,保证
MYSQL_*与ASTRNEST_DB_*指向同一个实例; - 再设置管理员用户名/密码/邮箱,以便初始化脚本创建正确的超级管理员;
- 根据部署拓扑写入站点域名、图片访问域名、后端公开地址,并在 Nginx 或负载均衡层做好
/upload/**映射; - 如需发邮件,提前准备好 SMTP 主机、端口与授权码;
- 如需 AI 审核,准备好腾讯云 COS CI 的 SecretId/SecretKey;
- 最后把前端访问后端的
VITE_API_BASE_URL、图片直链VITE_PUBLIC_ASSET_BASE调整为公网域名。
重点变量:
MYSQL_ROOT_PASSWORD/MYSQL_DATABASE/MYSQL_USER/MYSQL_PASSWORD:mysql容器初始化所需的库名与账号密码,也方便 DBA 直接照抄到现有 MySQL 主机。ASTRNEST_DB_URL/ASTRNEST_DB_USERNAME/ASTRNEST_DB_PASSWORD:后端 JDBC 连接串、账号、密码;Docker 模式下可直接写jdbc:mysql://mysql:3306/${MYSQL_DATABASE}?...,裸机部署时改为真实主机。ASTRNEST_STORAGE_ROOT:容器内/宿主机映射的真实目录,示例./storage/upload:/storage/upload。系统会自动在目录下创建YYYY/MM子目录。ASTRNEST_STORAGE_PUBLIC:对外路径前缀,默认为/upload,因此直链为https://站点/upload/{yyyy}/{MM}/{文件名}。ASTRNEST_STORAGE_STRATEGY:存储策略,可选LOCAL、ALIYUN_OSS、TENCENT_COS、S3_COMPATIBLE、UPYUN_USS、ONEDRIVE等。ASTRNEST_ASSET_DOMAIN+PUBLIC_SITE_URL/PUBLIC_ASSET_URL/BACKEND_API_PUBLIC_URL:若要把资产托管到 CDN,请在这里写实际域名,并在 Nginx/Caddy 中增加/upload/**反代;PUBLIC_SITE_URL用于在邮件等场景拼接站点主页。ASTRNEST_MULTIPART_MAX_FILE_SIZE/ASTRNEST_MULTIPART_MAX_REQUEST_SIZE:必须保持20MB以内,否则会与数据库CHECK (size <= 20971520)冲突。ASTRNEST_ADMIN_*:首次启动自动落库的管理员信息;密码落库前会以 bcrypt 存储。SMTP_*:与 init.sql 中的chenxi_mail_config占位值保持一致,方便后续导入。ASTRNEST_AI_TENCENT_*:腾讯云 AI 审核配置,包括 SecretId、SecretKey、Region、Bucket、检测场景、置信度阈值等。ASTRNEST_VIDEO_THUMBNAIL_*:视频缩略图配置,包括 enabled、ffmpeg-path、capture-offset、quality 等。VITE_API_BASE_URL/VITE_PUBLIC_ASSET_BASE/VITE_SITE_NAME:前端构建期注入,用于 axios、复制直链按钮与浏览器标签标题。
3. 后端配置 (application.yml)
- 位置:
backend/src/main/resources/application.yml - 默认已经引用上述环境变量;若需写死,可以改为纯字符串:
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/astrnest?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: astrnest
password: astrnestPass!
servlet:
multipart:
max-file-size: 20MB
max-request-size: 20MB
astrnest:
storage:
strategy: LOCAL
local:
root: /storage/upload
public-base-url: /upload
admin:
username: admin
password: chenxi123
display-name: 超级管理员
email: admin@example.com重要:
public-base-url只能使用相对路径(以/upload开头),否则 Spring 的静态资源映射不起作用;若要使用 CDN 域名,请在后台"系统配置"中填写asset_domain。
4. 数据库初始化
4.1 Linux / macOS(推荐执行方式)
mysql -u root -p < backend/db/init.sql4.2 Windows(Navicat / GUI 导入兼容说明)
在 Windows 上使用 Navicat "导入 SQL 文件"时,可能会因为以下原因失败:
- 权限不足(
CREATE USER/GRANT/FLUSH PRIVILEGES需要高权限账号); DELIMITER/ 多语句 /PREPARE ... EXECUTE ...动态 SQL 在某些导入模式下会被拆分导致语法错误。
为此项目已提供 Windows/Navicat 友好版脚本:backend/db/init_windows.sql。
- 该脚本用于"新库初始化"更稳定(移除了大量动态迁移段、触发器改为不依赖
DELIMITER的写法)。 - 注意:
init_windows.sql默认不做CREATE USER/GRANT,避免普通连接账号导入时报错;因此需要你额外手工授权(见 4.3)。
推荐导入流程(Navicat):
- 用
root(或 DBA)在 Navicat 先手动创建数据库astrnest(字符集utf8mb4)。 - 选中库
astrnest后导入并执行backend/db/init_windows.sql。 - 如导入时报"没有 CREATE VIEW / CREATE TRIGGER 权限",请用更高权限账号执行导入,或临时注释掉
CREATE VIEW/CREATE TRIGGER段。
4.3 常见启动报错:1044 / 42000(账号能登录但无库权限)
如果你在命令行能 mysql -u astrnest -p 登录,但后端启动报错:
SQL Error: 1044, SQLState: 42000Access denied for user 'astrnest'@'localhost' to database 'astrnest'
说明:账号/密码正确,但 astrnest@host 没有 astrnest.* 的权限。用 root(或 DBA)执行下面 SQL:
CREATE DATABASE IF NOT EXISTS astrnest CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS 'astrnest'@'localhost' IDENTIFIED BY 'chenxi123';
CREATE USER IF NOT EXISTS 'astrnest'@'%' IDENTIFIED BY 'chenxi123';
GRANT ALL PRIVILEGES ON astrnest.* TO 'astrnest'@'localhost';
GRANT ALL PRIVILEGES ON astrnest.* TO 'astrnest'@'%';
FLUSH PRIVILEGES;说明:MySQL 用户是按
用户@Host匹配的,常见坑是只授权了astrnest@'%',但实际连接被识别成astrnest@'localhost'(或反过来)。
验证方式:
SHOW GRANTS FOR 'astrnest'@'localhost';
SHOW GRANTS FOR 'astrnest'@'%';
USE astrnest;
SHOW TABLES;5. 前端环境文件
- 位置:
frontend/.env.development/frontend/.env.production(可自建),亦可在构建命令行注入。 - 推荐内容:
VITE_API_BASE_URL=https://api.astrnest.com
VITE_PUBLIC_ASSET_BASE=https://cdn.astrnest.com/upload
VITE_SITE_NAME=AstrNest6. 上传与静态资源
- 目录结构:
LocalStorageHandler会把每个文件写入${ASTRNEST_STORAGE_ROOT}/{yyyy}/{MM}/文件名。 - 默认访问:若
asset_domain为空,后台会返回/upload/{yyyy}/{MM}/文件名,浏览器会基于当前域名访问。 - 反向代理:需要在 Nginx/网关层补上一段:
location /upload/ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080/upload/;
}- CDN/自定义域:在后台 -> 系统配置填入
https://cdn.xxx.com,或在数据库system_config.asset_domain中直接写;API 会把图片 URL 改为https://cdn.xxx.com/upload/{...}。
7. AI 内容审核配置
7.1 腾讯云 COS CI 配置
在 .env 中配置:
ASTRNEST_AI_TENCENT_SECRET_ID=your-secret-id
ASTRNEST_AI_TENCENT_SECRET_KEY=your-secret-key
ASTRNEST_AI_TENCENT_REGION=ap-beijing
ASTRNEST_AI_TENCENT_BUCKET=your-bucket-1250000000
ASTRNEST_AI_TENCENT_DETECT_SCENES=web,camera,album,news
ASTRNEST_AI_BLOCK_CONFIDENCE=90
ASTRNEST_AI_REVIEW_CONFIDENCE=60
ASTRNEST_AI_LABEL_MIN_CONFIDENCE=60或在后台「系统配置 > AI 智能审核」中填写:
- SecretId/SecretKey:腾讯云 API 密钥
- Region:存储桶所在地域,如
ap-beijing - Bucket:存储桶名称,如
your-bucket-1250000000 - 检测场景:
web,camera,album,news等 - 拦截阈值:建议 90(置信度 >=90 直接拦截)
- 复核阈值:建议 60(置信度 60-90 需人工复核)
- 标签阈值:建议 60(置信度 >=60 的标签会保存)
官方参考:https://cloud.tencent.com/document/product/460/37318
8. 视频缩略图(FFmpeg)
8.1 安装 FFmpeg
- Debian/Ubuntu:
sudo apt-get install -y ffmpeg - CentOS/RHEL:
sudo yum install -y ffmpeg(或dnf) - macOS:
brew install ffmpeg - Windows:下载官方 build,将
bin加入 PATH;或者使用chocolatey/winget安装(choco install ffmpeg、winget install ffmpeg)
8.2 配置
在 .env 中配置:
ASTRNEST_VIDEO_THUMBNAIL_ENABLED=true
ASTRNEST_VIDEO_THUMBNAIL_FFMPEG_PATH=ffmpeg
ASTRNEST_VIDEO_THUMBNAIL_CAPTURE_OFFSET=5
ASTRNEST_VIDEO_THUMBNAIL_QUALITY=80
ASTRNEST_VIDEO_THUMBNAIL_TIMEOUT_SECONDS=30
ASTRNEST_VIDEO_THUMBNAIL_COVER_DIRECTORY=/storage/upload/covers
ASTRNEST_VIDEO_THUMBNAIL_MAX_LOAD_AVERAGE=4.08.3 常见日志:找不到 ffmpeg(不影响服务启动)
如果日志出现类似:
Cannot run program "ffmpeg": error=2, No such file or directory
说明后端在生成视频封面/缩略图时找不到 ffmpeg,一般不影响后端启动,但会导致视频封面生成失败。
- 解决方案 A(推荐):安装 ffmpeg 并确保命令行可直接执行
ffmpeg; - 解决方案 B:如果你暂时不需要视频封面,设置环境变量
ASTRNEST_VIDEO_THUMBNAIL_ENABLED=false。
9. 邮件设置
- 启动后:后台「设置 > 邮件服务」填 SMTP 主机/端口/账号/授权码/发件人。
- 若希望脚本写入真实值:编辑
backend/db/init.sql中INSERT INTO chenxi_mail_config段。
10. Docker Compose 部署
cp .env.example .env并填好所有占位。- 执行:
docker compose --env-file .env up -d- 默认行为:启动 MySQL、导入
init.sql、启动 backend(8080) 与 frontend(80),挂载./storage/upload。 - 如需 JVM/调试参数:在
.env设置JAVA_OPTS,Compose 会透传。
11. 传统部署
- 后端:
cd backend && ./mvnw clean package && java -jar target/backend-0.0.1-SNAPSHOT.jar - 前端:
cd frontend && npm run build,将dist/交给 Nginx/CDN。
11.1 Windows 启动命令
Windows 下建议使用 Maven Wrapper:
- 编译/运行:
cd backend && .\mvnw.cmd spring-boot:run - 打包:
cd backend && .\mvnw.cmd clean package
说明:如果直接使用
mvn报 "不是内部或外部命令",说明你本机没有安装 Maven 或未加入 PATH;使用项目自带的mvnw.cmd可以避免这个问题。
11.2 Windows 控制台中文日志乱码(UTF-8 编码)
如果你看到日志里中文变成类似 鏈娴... 的乱码,通常不是业务问题,而是 终端编码与 Java 输出编码不一致。
推荐做法(Windows Terminal / PowerShell):
- 先把当前会话切到 UTF-8:
chcp 65001
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8- 再启动后端:
cd backend
.\mvnw.cmd spring-boot:runIDE 控制台(IntelliJ IDEA):
- 将
Settings > Editor > File Encodings设置为 UTF-8; - 运行配置(Run/Debug Configuration)里确保控制台编码为 UTF-8(不同版本位置略有差异)。
示例:这条乱码日志的原文一般是
未检测到激活的存储策略,沿用配置文件默认值: LOCAL。
12. 收尾检查
.env、application.yml、frontend/.env*均已替换真实地址/账号。backend/db/init.sql(或 Windows 下的backend/db/init_windows.sql)中管理员邮箱/SMTP/资产域名已调整。- 访问健康检查:
http://{server}:8080/actuator/health应为UP;/upload/{yyyy}/{MM}/...能返回 200/404(不应 502)。
12.1 常见"能跑但日志报错"的说明(排障速查)
12.1.1 No converter for ApiErrorResponse with preset Content-Type 'video/mp4'
如果你在日志里看到类似:
HttpMessageNotWritableException: No converter for [class ...ApiErrorResponse] with preset Content-Type 'video/mp4'
含义:你请求的是视频/资源(响应本来应该是 video/mp4 或二进制流),但中途抛异常后框架想返回 JSON 错误体;由于响应头 Content-Type 已经是 video/mp4,就会出现"无法用 mp4 的 Content-Type 写 JSON"这种报错。
处理建议(按优先级):
- 先看触发该报错的请求路径:通常是访问视频直链或资源接口(例如
/upload/**或/api/uploads/**等)。 - 确认资源文件确实存在、存储路径配置正确(本地存储是否挂载到正确目录)。
- 若你是在浏览器/播放器里访问,尽量避免手动强行设置
Accept: video/mp4后再去请求会返回 JSON 的接口。
这类报错通常不影响服务启动,但会导致那一次请求返回失败。
13. Nginx 反向代理与静态加速示例
13.1 基本反代(前端 + 后端 + 上传)
# 前端 SPA(dist 部署)
server {
listen 80;
server_name example.com;
root /var/www/astrnest/dist;
location / {
try_files $uri $uri/ /index.html;
}
# 上传直链透传后端(若使用本地存储)
location /upload/ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080/upload/;
expires 7d;
add_header Cache-Control "public";
}
# 后端 API
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8080/api/;
}
# OpenAPI / Swagger
location /swagger-ui/ {
proxy_pass http://127.0.0.1:8080/swagger-ui/;
}
}13.2 HTTPS/HTTP2 与常用优化
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy strict-origin-when-cross-origin;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()";
gzip on;
gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml;
gzip_vary on;
# 其余 location 同 13.1,可复用
}14. CDN / 直链域名配置
- 在后台"系统配置"填写
asset_domain(如https://cdn.example.com),前端复制直链会自动拼成asset_domain + /upload/{yyyy}/{MM}/...。 - 如使用前端环境变量控制:设置
VITE_PUBLIC_ASSET_BASE=https://cdn.example.com/upload。 - Nginx 只需把
/upload/回源到后端或对象存储源站;如走 OSS/COS,请在 CDN 源站指向对应桶域名或自建反代。
15. 对象存储配置示例
15.1 阿里云 OSS(application.yml 片段)
astrnest:
storage:
strategy: ALIYUN_OSS
oss:
enabled: true
endpoint: https://oss-cn-shanghai.aliyuncs.com
bucket: astrnest-prod
access-key: ${ALIYUN_ACCESS_KEY}
secret-key: ${ALIYUN_SECRET_KEY}
cdn-host: https://cdn.example.com # 可选CDN 生效后,前端建议同时设置
VITE_PUBLIC_ASSET_BASE=https://cdn.example.com/upload。
15.2 腾讯云 COS
astrnest:
storage:
strategy: TENCENT_COS
cos:
enabled: true
endpoint: https://cos.ap-shanghai.myqcloud.com
region: ap-shanghai
bucket: astrnest-1250000000
access-key: ${TENCENT_SECRET_ID}
secret-key: ${TENCENT_SECRET_KEY}
path-style: true
accelerate: false
multipart-threshold-mb: 5120
part-size-mb: 25
cdn-host: https://cos-cdn.example.com # 可选15.3 通用 S3 兼容
astrnest:
storage:
strategy: S3_COMPATIBLE
s3:
enabled: true
endpoint: https://s3.us-east-1.amazonaws.com
region: us-east-1
bucket: astrnest-archive
access-key: ${AWS_ACCESS_KEY}
secret-key: ${AWS_SECRET_KEY}
path-style: true若供应商要求 virtual-host 模式,关闭
path-style并确保域名已做 CNAME。
15.4 又拍云 USS
astrnest:
storage:
strategy: UPYUN_USS
upyun:
enabled: true
bucket: astrnest
operator: ${UPYUN_OPERATOR}
password: ${UPYUN_OPERATOR_PASSWORD}
endpoint: https://v0.api.upyun.com
cdn-host: https://static.example.com15.5 OneDrive / SharePoint
astrnest:
storage:
strategy: ONEDRIVE
onedrive:
enabled: true
drive-type: business # personal / business
tenant-id: ${AZURE_TENANT_ID}
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
drive-id: ${ONEDRIVE_DRIVE_ID}
site-id: ${SHAREPOINT_SITE_ID}
refresh-token: ${ONEDRIVE_REFRESH_TOKEN} # 个人盘常用
base-url: https://graph.microsoft.com/v1.0
drive-id优先级高于site-id;未配置 refresh token 时企业盘可用 client credentials 获取 Token。
16. 前端/后端分域部署示例
- 前端域名:
https://console.example.com(托管 dist) - API 域名:
https://api.example.com(反代后端) - 直链/CDN 域名:
https://cdn.example.com/upload - 前端环境:
VITE_API_BASE_URL=https://api.example.com
VITE_PUBLIC_ASSET_BASE=https://cdn.example.com/upload
VITE_SITE_NAME=AstrNest- 后端系统配置:
asset_domain=https://cdn.example.com - Nginx:前端站点只需静态托管;API 与 /upload 由 api 域名回源后端或对象存储。
完成以上补充后,可直接按本文示例配置并上线。