生产部署
生产部署
本篇讲解用 MySQL + Nginx 把平台部署到生产服务器(非容器方式)。容器化部署见 。
部署架构
浏览器
│
▼
Nginx (:80/:443)
├── / -> 前端静态文件 (dist/)
└── /api/** -> 反代到后端 (:52856)
│
▼
Spring Boot (mysql profile)
│
┌───────┴───────┐
▼ ▼
MySQL 8.x Redis 6+端口约定
- 后端应用监听
52856(application.yml中server.port: 52856)。 - Nginx 对外暴露
80(HTTP)或443(HTTPS)。 - 生产环境通常不暴露后端端口,仅由 Nginx 内部反代
/api。
一、准备数据库
1. 建库
CREATE DATABASE lowcode CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;2. 导入表结构与数据
不要只用 schema-mysql.sql
backend/src/main/resources/schema-mysql.sql 仅含 16 张表,远落后于实际所需的 53+ 张表。生产 MySQL 初始化请用下面的推荐组合,详见 。
# 推荐导入组合(按顺序执行)
mysql -u root -p lowcode < docs/SQL_INIT.sql # 基础 13 表
mysql -u root -p lowcode < docs/SQL_EXTENSION.sql # BPM/ERP/消息/报表扩展 48 表
mysql -u root -p lowcode < sql/mysql/bpm.sql # 芋道风格 BPM 8 表
mysql -u root -p lowcode < sql/mysql/hr_employee.sql # 员工表
mysql -u root -p lowcode < backend/src/main/resources/data-mysql.sql # BPM 表补列修复
mysql -u root -p lowcode < sql/mysql/migration-column-meta-options.sql # lc_column_meta 补列(幂等)3. 创建应用账号(推荐,非必需)
CREATE USER 'lowcode'@'%' IDENTIFIED BY '你的强密码';
GRANT ALL PRIVILEGES ON lowcode.* TO 'lowcode'@'%';
FLUSH PRIVILEGES;二、构建后端
cd backend
# 编译打包(跳过测试)
mvn clean package -DskipTests产物:backend/target/lowcode-platform-1.0.0.jar(Spring Boot Fat Jar)。
JDK 版本
构建与运行均使用 JDK 17。JDK 21 + Maven 命令行构建会触发 Lombok TypeTag 错误,详见 。
三、启动后端
基本启动
java -Xms512m -Xmx2048m \
-jar lowcode-platform-1.0.0.jar \
--spring.profiles.active=mysql关于 prod profile
项目没有内置 application-prod.yml,只内置了 h2 与 mysql 两个 profile(application.yml 默认 active: mysql)。生产环境直接使用 mysql profile,通过环境变量覆盖敏感配置(数据源、Redis、端口等);若需要独立的 prod 配置文件,可自行创建 application-prod.yml 并用 --spring.profiles.active=prod 激活。
用环境变量覆盖配置
application.yml / application-mysql.yml 中所有配置项均已支持环境变量占位。生产推荐用环境变量注入:
export SERVER_PORT=52856
export SPRING_DATASOURCE_URL='jdbc:mysql://生产MySQL:3306/lowcode?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true'
export SPRING_DATASOURCE_USERNAME=lowcode
export SPRING_DATASOURCE_PASSWORD='你的强密码'
export REDIS_HOST=生产Redis地址
export REDIS_PORT=6379
export REDIS_PASSWORD='Redis密码'
export API_DEBOUNCE_ENABLED=true
java -Xms512m -Xmx2048m -jar lowcode-platform-1.0.0.jar --spring.profiles.active=mysqlapplication-mysql.yml 默认数据源(需改)
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/lowcode?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: Admin123.
sql:
init:
mode: never # 生产不自动建表,需手动导入
schema-locations: classpath*:sql/mysql/*.sql默认密码是 Admin123.,生产务必修改。
上传文件大小
application.yml 已配置:
spring:
servlet:
multipart:
max-file-size: 20MB
max-request-size: 50MBNginx 侧需对应放开 client_max_body_size(见下文 Nginx 配置),否则大文件上传会被 Nginx 拦截。
后台常驻运行
推荐用 systemd 或 nohup:
# nohup 方式(简单)
nohup java -Xms512m -Xmx2048m -jar lowcode-platform-1.0.0.jar \
--spring.profiles.active=mysql > lowcode.log 2>&1 &四、构建前端
cd frontend
pnpm install
pnpm build产物:frontend/dist/。将整个 dist/ 目录上传到服务器(如 /usr/share/nginx/html/lowcode/)。
用 npm 构建
npm install
npm run build五、配置 Nginx
生产 Nginx 需做两件事:托管前端静态文件、反代 /api 到后端。
server {
listen 80;
server_name your-domain.com;
# 上传文件大小,与后端 max-request-size: 50MB 对齐
client_max_body_size 50M;
root /usr/share/nginx/html/lowcode;
index index.html;
# gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/json application/xml;
# 前端路由(Vue Router history 模式)
location / {
try_files $uri $uri/ /index.html;
}
# 后端 API 反代
location /api {
proxy_pass http://127.0.0.1:52856/api;
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_read_timeout 60s;
proxy_send_timeout 60s;
}
# 上传文件访问(后端 file.upload.url-prefix: /uploads/)
location /uploads/ {
proxy_pass http://127.0.0.1:52856/uploads/;
}
# 静态资源长缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}proxy_pass 与 /api 前缀
后端控制器统一以 /api/xxx 为前缀(如 @RequestMapping("/api/auth"))。Nginx 反代时 proxy_pass http://127.0.0.1:52856/api 会保留 /api 前缀透传给后端,与后端路由对齐。不要在后端再加一层 /api,否则会变成 /api/api/xxx 导致 404,详见 。
HTTPS
生产建议配置 HTTPS(Let's Encrypt 免费证书)。在 Nginx 增加 listen 443 ssl 与证书路径,并将 80 端口 301 重定向到 443。
重载 Nginx:
nginx -t # 检查配置语法
nginx -s reload # 平滑重载六、验证
- 浏览器访问
http://your-domain.com,应看到登录页。 - 用默认账号登录(MySQL 首次启动默认
admin / admin123,可被-Dapp.admin.password覆盖,详见 )。 - 触发一次列表查询,确认
/api/**反代正常、无 404。 - 上传一个文件,确认
client_max_body_size生效。
七、生产检查清单
- [ ] MySQL 密码已修改(非
Admin123./root) - [ ] Redis 密码已设置(默认远程
124.71.29.50:6379有硬编码密码,生产务必换成自有 Redis) - [ ]
jwt.secret已改为随机强密钥(默认lowcode-platform-secret-key-2024-...不可用于生产) - [ ] JDK 17 运行环境
- [ ] Nginx
client_max_body_size 50M - [ ] 数据库已按推荐组合导入完整 SQL
- [ ] 后端以
systemd/ 守护进程方式常驻 - [ ] 日志目录可写(
./logs/、./uploads/) - [ ] 确认 中列出的坑已处理
JWT 密钥必须修改
application.yml 中 jwt.secret 是公开默认值。生产环境若不修改,攻击者可伪造合法 JWT 登录任意账号。请通过环境变量或自定义 application-prod.yml 注入随机密钥。
# 示例:通过启动参数覆盖(也可用环境变量 JWT_SECRET 等占位,需自行在 yml 中加 ${JWT_SECRET:默认值})
java -Djwt.secret=你的随机密钥 -jar lowcode-platform-1.0.0.jar --spring.profiles.active=mysql下一步:如需容器化部署,见 ;如遇环境问题,见 。
