Files

312 lines
14 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================
-- 应用商店数据库 —— 建表 + 初始数据
-- 数据库: my_panel
-- 字符集: utf8mb4
-- ============================================================
-- ─── 主表 ───
CREATE TABLE IF NOT EXISTS app_templates (
id INT AUTO_INCREMENT PRIMARY KEY,
app_key VARCHAR(64) NOT NULL UNIQUE COMMENT '唯一标识 (redis / mysql)',
name VARCHAR(128) NOT NULL COMMENT '显示名称',
tagline VARCHAR(256) DEFAULT NULL COMMENT '一句话描述',
description TEXT DEFAULT NULL COMMENT '详细描述',
icon VARCHAR(32) DEFAULT NULL COMMENT '图标标识 (redis / mysql)',
category VARCHAR(64) DEFAULT NULL COMMENT '分类',
image VARCHAR(256) NOT NULL COMMENT 'Docker 镜像',
container_name VARCHAR(128) NOT NULL COMMENT '容器名称',
network VARCHAR(128) DEFAULT '' COMMENT 'Docker 网络',
restart VARCHAR(32) DEFAULT 'always' COMMENT '重启策略',
hostname VARCHAR(128) DEFAULT '' COMMENT '容器主机名',
workdir VARCHAR(256) DEFAULT '' COMMENT '工作目录',
command TEXT DEFAULT NULL COMMENT '启动命令',
extra_args TEXT DEFAULT NULL COMMENT '额外 docker run 参数模板 (含 {{}} 占位符)',
sort_order INT DEFAULT 0 COMMENT '排序权重',
is_active TINYINT(1) DEFAULT 1 COMMENT '是否上架 1=是 0=否',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='应用模板主表';
-- ─── 子表:端口映射 ───
CREATE TABLE IF NOT EXISTS app_ports (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
host_port VARCHAR(16) NOT NULL COMMENT '宿主机端口',
container_port VARCHAR(16) NOT NULL COMMENT '容器端口',
protocol VARCHAR(8) DEFAULT 'tcp' COMMENT '协议',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:挂载卷 ───
CREATE TABLE IF NOT EXISTS app_volumes (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
host_path VARCHAR(512) NOT NULL COMMENT '宿主机路径',
container_path VARCHAR(512) NOT NULL COMMENT '容器路径',
mode VARCHAR(4) DEFAULT 'rw' COMMENT '读写模式',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:环境变量 ───
CREATE TABLE IF NOT EXISTS app_envs (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
env_key VARCHAR(256) NOT NULL COMMENT '变量名',
env_value TEXT DEFAULT NULL COMMENT '变量值 (含 {{}} 占位符)',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:自动创建目录 ───
CREATE TABLE IF NOT EXISTS app_mkdirs (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
dir_path VARCHAR(512) NOT NULL COMMENT '宿主机目录',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:自动写入配置文件 ───
CREATE TABLE IF NOT EXISTS app_write_files (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
file_path VARCHAR(512) NOT NULL COMMENT '宿主机文件路径',
file_content LONGTEXT NOT NULL COMMENT '文件内容 (含 {{}} 占位符)',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:用户参数 ───
CREATE TABLE IF NOT EXISTS app_params (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
param_key VARCHAR(64) NOT NULL COMMENT '参数键',
label VARCHAR(128) NOT NULL COMMENT '显示标签',
type VARCHAR(16) DEFAULT 'text' COMMENT 'text/password/number',
placeholder VARCHAR(256) DEFAULT NULL,
default_value VARCHAR(256) DEFAULT '' COMMENT '默认值',
required TINYINT(1) DEFAULT 0 COMMENT '是否必填',
options TEXT DEFAULT NULL COMMENT '下拉选项 JSON 数组 [{"value":"","label":""}]',
show_when VARCHAR(128) DEFAULT NULL COMMENT '条件显示 param_key:value',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ============================================================
-- 初始数据:Redis 模板
-- ============================================================
INSERT INTO app_templates (app_key, name, tagline, description, icon, category, image, container_name, network, restart, hostname, workdir, command, sort_order, is_active)
VALUES ('redis', 'Redis', '高性能内存数据库 / 缓存',
'Redis 是开源的内存数据结构存储,用作数据库、缓存、消息队列和流引擎。支持字符串、哈希、列表、集合等多种数据结构。',
'redis', '缓存', 'redis:8.10.0', 'redis', '', 'always', 'redis', '/data',
'redis-server /etc/redis/redis.conf', 1, 1);
SET @redis_id = LAST_INSERT_ID();
INSERT INTO app_ports (template_id, host_port, container_port, protocol, sort_order) VALUES
(@redis_id, '6379', '6379', 'tcp', 0);
INSERT INTO app_volumes (template_id, host_path, container_path, mode, sort_order) VALUES
(@redis_id, '/opt/redis/data', '/data', 'rw', 0),
(@redis_id, '/opt/redis/conf/redis.conf', '/etc/redis/redis.conf', 'rw', 1),
(@redis_id, '/opt/redis/logs', '/logs', 'rw', 2);
INSERT INTO app_mkdirs (template_id, dir_path, sort_order) VALUES
(@redis_id, '/opt/redis/data', 0),
(@redis_id, '/opt/redis/conf', 1),
(@redis_id, '/opt/redis/logs', 2);
INSERT INTO app_write_files (template_id, file_path, file_content, sort_order) VALUES
(@redis_id, '/opt/redis/conf/redis.conf',
'# Redis 配置文件
bind 0.0.0.0
protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 密码(部署时替换,留空则无密码)
{{REDIS_PASSWORD_LINE}}', 0);
INSERT INTO app_params (template_id, param_key, label, type, placeholder, default_value, required, sort_order) VALUES
(@redis_id, 'REDIS_PASSWORD', 'Redis 密码', 'password', '留空则无密码', '', 0, 0),
(@redis_id, 'PORT', '宿主机端口', 'number', '6379', '6379', 1, 1);
-- ============================================================
-- 初始数据:MySQL 模板
-- ============================================================
INSERT INTO app_templates (app_key, name, tagline, description, icon, category, image, container_name, network, restart, hostname, workdir, command, sort_order, is_active)
VALUES ('mysql', 'MySQL', '关系型数据库',
'MySQL 是最流行的开源关系型数据库管理系统,支持事务、存储过程、触发器、视图等完整 SQL 功能。此模板基于 MySQL 8.4 LTS。',
'mysql', '数据库', 'mysql:8.4.11', 'mysql', '', 'always', 'mysql', '/', '', 2, 1);
SET @mysql_id = LAST_INSERT_ID();
INSERT INTO app_ports (template_id, host_port, container_port, protocol, sort_order) VALUES
(@mysql_id, '3306', '3306', 'tcp', 0);
INSERT INTO app_volumes (template_id, host_path, container_path, mode, sort_order) VALUES
(@mysql_id, '/opt/mysql/data', '/var/lib/mysql', 'rw', 0),
(@mysql_id, '/opt/mysql/conf/my.cnf', '/etc/my.cnf', 'rw', 1),
(@mysql_id, '/opt/mysql/log', '/var/log/mysql', 'rw', 2),
(@mysql_id, '/etc/timezone', '/etc/timezone', 'ro', 3),
(@mysql_id, '/etc/localtime', '/etc/localtime', 'ro', 4);
INSERT INTO app_envs (template_id, env_key, env_value, sort_order) VALUES
(@mysql_id, 'MYSQL_ROOT_PASSWORD', '{{MYSQL_ROOT_PASSWORD}}', 0);
INSERT INTO app_mkdirs (template_id, dir_path, sort_order) VALUES
(@mysql_id, '/opt/mysql/data', 0),
(@mysql_id, '/opt/mysql/conf', 1),
(@mysql_id, '/opt/mysql/log', 2);
INSERT INTO app_write_files (template_id, file_path, file_content, sort_order) VALUES
(@mysql_id, '/opt/mysql/conf/my.cnf',
'# MySQL 配置文件
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 最大连接数
max_connections = 200
# Innodb
innodb_buffer_pool_size = 128M
innodb_log_file_size = 48M
innodb_flush_log_at_trx_commit = 1
# 日志
log-error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# 端口
port = 3306
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4', 0);
INSERT INTO app_params (template_id, param_key, label, type, placeholder, default_value, required, sort_order) VALUES
(@mysql_id, 'MYSQL_ROOT_PASSWORD', 'Root 密码', 'password', '设置 root 用户密码', '', 1, 0),
(@mysql_id, 'PORT', '宿主机端口', 'number', '3306', '3306', 1, 1);
-- ============================================================
-- 初始数据:Halo 模板
-- ============================================================
INSERT INTO app_templates (app_key, name, tagline, description, icon, category, image, container_name, network, restart, hostname, workdir, command, extra_args, sort_order, is_active)
VALUES ('halo', 'Halo', '强大易用的开源建站工具',
'Halo 是一款开源的建站工具,支持博客、CMS、企业官网等多种场景。内置主题管理、插件系统、多用户、SEO 等功能。社区版基于开源仓库构建,免费使用。',
'halo', '建站', 'registry.fit2cloud.com/halo/halo:2.26', 'halo', '', 'always', 'halo', '', '', '{{HALO_DB_ARGS}}', 3, 1);
SET @halo_id = LAST_INSERT_ID();
INSERT INTO app_ports (template_id, host_port, container_port, protocol, sort_order) VALUES
(@halo_id, '{{PORT}}', '8090', 'tcp', 0);
INSERT INTO app_volumes (template_id, host_path, container_path, mode, sort_order) VALUES
(@halo_id, '/opt/halo/data', '/root/.halo2', 'rw', 0);
INSERT INTO app_envs (template_id, env_key, env_value, sort_order) VALUES
(@halo_id, 'JVM_OPTS', '-Xmx{{JVM_MAX}} -Xms{{JVM_MIN}}', 0);
INSERT INTO app_mkdirs (template_id, dir_path, sort_order) VALUES
(@halo_id, '/opt/halo/data', 0);
INSERT INTO app_params (template_id, param_key, label, type, placeholder, default_value, required, options, show_when, sort_order) VALUES
(@halo_id, 'PORT', '宿主机端口', 'number', '8090', '8090', 1, NULL, NULL, 0),
(@halo_id, 'JVM_MAX', 'JVM 最大内存', 'text', '256m', '256m', 1, NULL, NULL, 1),
(@halo_id, 'JVM_MIN', 'JVM 初始内存', 'text', '256m', '256m', 1, NULL, NULL, 2),
(@halo_id, 'DB_TYPE', '数据库', 'select', 'H2 内置数据库', 'h2', 1, '[{"value":"h2","label":"H2 内置数据库(零配置)"},{"value":"mysql","label":"MySQL 外部数据库"}]', NULL, 3),
(@halo_id, 'DB_HOST', 'MySQL 地址', 'text', '127.0.0.1', '127.0.0.1', 0, NULL, 'DB_TYPE:mysql', 4),
(@halo_id, 'DB_PORT', 'MySQL 端口', 'number', '3306', '3306', 0, NULL, 'DB_TYPE:mysql', 5),
(@halo_id, 'DB_NAME', 'MySQL 库名', 'text', 'halodb', 'halodb', 0, NULL, 'DB_TYPE:mysql', 6),
(@halo_id, 'DB_USER', 'MySQL 用户名', 'text', 'root', 'root', 0, NULL, 'DB_TYPE:mysql', 7),
(@halo_id, 'DB_PASSWORD', 'MySQL 密码', 'password', '数据库密码', '', 0, NULL, 'DB_TYPE:mysql', 8);
-- Halo 的 extra_args ({{HALO_DB_ARGS}}) 由前端 tplWithDerived 函数动态解析,
-- 根据 DB_TYPE 参数自动生成 MySQL 连接环境变量或留空(H2 模式)
-- ============================================================
-- 客户端版本管理表
-- ============================================================
CREATE TABLE IF NOT EXISTS app_version (
id INT AUTO_INCREMENT PRIMARY KEY,
version VARCHAR(32) NOT NULL UNIQUE COMMENT '版本号 (如 v0.0.1)',
download_url VARCHAR(512) NOT NULL COMMENT '下载地址',
release_notes TEXT DEFAULT NULL COMMENT '更新说明',
is_latest TINYINT(1) DEFAULT 0 COMMENT '是否为最新版本 1=是 0=否',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户端版本管理';
-- 初始版本数据:v0.0.1
INSERT INTO app_version (version, download_url, release_notes, is_latest, created_at)
VALUES ('v0.0.1', 'https://114.66.55.63:3001/download/wfj-panel-v0.0.1.exe',
'WFJ Panel 首个版本 v0.0.1
功能列表:
- SSH 远程服务器连接管理
- 服务器概览监控(CPU/内存/硬盘/网络/进程)
- 远程文件管理(上传/下载/新建/删除)
- 交互式终端(xterm.js)
- Docker 容器管理(概览/容器列表/镜像/应用商店/任务中心/配置/网络/卷)
- 应用商店一键部署(Redis/MySQL/Halo)
- 系统防火墙管理(firewalld/ufw/iptables)', 0, NOW());
-- v0.0.2
INSERT INTO app_version (version, download_url, release_notes, is_latest, created_at)
VALUES ('v0.0.2', 'https://114.66.55.63:3001/download/wfj-panel-v0.0.2.exe',
'WFJ Panel v0.0.2 更新
新增功能:
- 应用商店新增 Java 应用模板(支持选择 Java 版本、自定义启动命令、端口映射、路径可视化选择)
- 运行时类容器支持重复部署(自动生成不重复容器名)
- 应用商店参数新增 path 类型(远程目录浏览器选择宿主机路径)
问题修复:
- 修复任务中心显示占位符 {{CONTAINER_NAME}} 未替换的问题
- 修复端口映射容器端口占位符未替换导致部署失败的问题
- 修复 execDeploy 超时后 SSH stream 未销毁导致 channel 泄漏
- 修复 select 类型参数无默认值时部署按钮误判为必填项未填而置灰
- docker pull 超时从 5 分钟提升到 10 分钟
其他改进:
- 窗口标题由 SSH Panel 改为 WFJ Panel
- 登录页 LOGO 改为 WFJ Panel', 1, NOW());