仪表盘

系统正常
官方网站
📁 网站总数
-
个站点
🗄️ 数据库
-
个数据库
💾 备份状态
-
份备份
🔐 安全更新
-
个待安装
🛡️
安全状态:已启用自动更新
系统每日 03:00 自动执行安全更新
⚡ 服务状态
🌿
Nginx
Web 服务器
运行中
🐬
MySQL
数据库服务
运行中
🐘
PHP-FPM
PHP 解释器
运行中
🛡️
UFW 防火墙
端口防护
已启用
💻 系统资源
CPU 负载
-
CPU 核心数
-
CPU 型号
-
内存
-
磁盘
-
负载均值
-

网站列表

域名 PHP 路径 状态 SSL 创建时间 操作

数据库

数据库名 用户 密码 字符集 创建时间 操作

SSL 证书

域名 证书路径 到期日期 自动续期 操作

备份记录

站点 类型 文件大小 状态 时间 操作

⌨️ 终端

快速命令:
TPanel Terminal v1.3.40.1 - 在此执行服务器命令 提示: · 直接输入命令按 Enter 执行 · 点击上方快速命令按钮自动填入 · 危险命令(rm -rf /、shutdown 等)会被拦截 · 当前工作目录:/root
$

安全中心

🛡️ 安全更新
-
个可用更新
❌ 近期错误
-
条系统错误
🔒 防火墙
-
状态
🛡️ 自动漏洞修复

T面板每日凌晨 03:00 自动执行 apt-get update && apt-get upgrade -y,修复已知安全漏洞。

最近执行:-

📁 文件管理

/
名称 大小 修改时间 权限 操作

⏰ 定时任务

任务名称 站点 执行周期 命令 状态 上次执行 操作

📦 软件市场

一键安装建站必备环境。安装过程中会显示实时进度。

加载中...

🔥 防火墙管理

加载中...

🔌 面板端口修改

⚠️ 修改端口后需要重新访问新端口的地址,防火墙会自动开放新端口。

💾 自动备份

📦 版本信息

当前版本
--
最新版本
--
状态
--
更新说明
--

⬆️ 手动升级

📦
拖拽安装包到这里,或点击选择文件
支持 tpanel-v*.zip 格式安装包

⏪ 版本回滚

升级前会自动备份当前版本,可以随时回滚
暂无备份

👤 修改管理员密码

⚙️ 系统设置

🔗 面板域名绑定

绑定后只能通过该域名访问后台(如留空则不限制访问来源)。绑定后请确保 DNS 已解析到此服务器。
⚠️ 修改域名绑定后需重启面板服务:systemctl restart tpanel

🌐 官方信息

📋 安全日志

500KB 用 textarea,否则用 CM5 const MAX_CM_SIZE = 500 * 1024; if (content.length > MAX_CM_SIZE) { console.warn('[CM5] file too large, fallback to textarea'); ta.value = content; ta.style.display = 'block'; container.style.display = 'none'; return; } // 根据后缀选 mode const ext = (filepath.split('.').pop() || '').toLowerCase(); const mode = modeMap[ext] || 'text/plain'; // 宝塔风格主题:深色用 material-darker,浅色用 default const theme = isDark ? 'material-darker' : 'default'; try { _cmEditor = CodeMirror(container, { value: content, mode: mode, theme: theme, lineNumbers: true, indentUnit: 4, tabSize: 4, indentWithTabs: false, autoCloseBrackets: true, matchBrackets: true, styleActiveLine: true, lineWrapping: true, extraKeys: { 'Ctrl-S': function() { saveFile(); }, 'Cmd-S': function() { saveFile(); } } }); // 强制 refresh(modal 刚打开时 width 可能为 0) setTimeout(() => { try { _cmEditor.refresh(); } catch(e){} }, 100); console.log('[v1.3.42 CM5] init done'); } catch (e) { console.error('[CM5] init failed, fallback textarea:', e); _cmEditor = null; ta.value = content; ta.style.display = 'block'; container.style.display = 'none'; } } } const ta = document.getElementById('fileEditor'); return ta ? ta.value : ''; } // ===================== // v1.3.39+ 在线升级 // ===================== async function loadUpgradePage() { const d = await api('/upgrade/version'); if (d.code !== 0) return; document.getElementById('currentVersion').textContent = d.data.data.current; document.getElementById('latestVersion').textContent = d.data.data.latest; document.getElementById('releaseNotes').textContent = d.data.data.release_notes; if (d.data.data.has_update) { document.getElementById('versionStatus').innerHTML = '✨ 有新版本可用'; } else { document.getElementById('versionStatus').innerHTML = '✅ 已是最新版本'; } renderUpgradeBackupList(d.backups); } function renderUpgradeBackupList(backups) { const container = document.getElementById('backupList'); if (!backups || backups.length === 0) { container.innerHTML = '
暂无备份
'; return; } container.innerHTML = backups.map(b => '
' + b.name + '
' + b.mtime + ' · ' + b.size + '
' ).join(''); } function handleUpgradeFile(input) { const file = input.files[0]; if (!file) return; if (!file.name.endsWith('.zip')) { alert('只支持 zip 格式'); return; } const formData = new FormData(); formData.append('file', file); fetch('/api/upgrade/upload', { method: 'POST', body: formData, credentials: 'same-origin' }) .then(r => r.json()) .then(d => { if (d.code === 0) { document.getElementById('uploadedFileName').textContent = file.name + ' (' + (file.size/1024).toFixed(1) + ' KB)'; document.getElementById('uploadDropZone').style.display = 'none'; document.getElementById('uploadedPackage').style.display = 'block'; } else { alert(d.msg); } }) .catch(e => alert('上传失败: ' + e.message)); } function cancelUpload() { document.getElementById('upgradeFileInput').value = ''; document.getElementById('uploadDropZone').style.display = 'block'; document.getElementById('uploadedPackage').style.display = 'none'; } async function runUpgrade() { if (!confirm('确定开始升级?升级过程中请勿关闭页面!')) return; document.getElementById('upgradeAlert').className = 'alert show'; document.getElementById('upgradeAlert').textContent = '⏳ 正在升级...'; document.getElementById('upgradeAlert').style.display = 'block'; const d = await api('/upgrade/run', { method: 'POST' }); if (d.code === 0) { document.getElementById('upgradeAlert').className = 'alert show success'; document.getElementById('upgradeAlert').textContent = '✅ ' + d.msg + ' 页面即将刷新...'; setTimeout(() => window.location.reload(), 3000); } else { document.getElementById('upgradeAlert').className = 'alert show error'; document.getElementById('upgradeAlert').textContent = '❌ ' + d.msg; } } async function rollbackTo(backupFile) { if (!confirm('确定回滚到此版本?')) return; document.getElementById('upgradeAlert').textContent = '⏳ 正在回滚...'; document.getElementById('upgradeAlert').style.display = 'block'; const d = await api('/upgrade/rollback', { method: 'POST', body: JSON.stringify({ backup_file: backupFile }) }); if (d.code === 0) { document.getElementById('upgradeAlert').className = 'alert show success'; document.getElementById('upgradeAlert').textContent = '✅ ' + d.msg; setTimeout(() => window.location.reload(), 3000); } else { document.getElementById('upgradeAlert').className = 'alert show error'; document.getElementById('upgradeAlert').textContent = '❌ ' + d.msg; } } // ===================== // Production / 生产增强功能 // ===================== async function loadProduction() { const fw = await api('/firewall/status'); if (fw.code === 0) { const status = fw.data; document.getElementById('fwStatus').innerHTML = '
防火墙类型:' + (status.type || '未检测到') + ' | 状态:' + (status.enabled ? '已启用' : '未启用') + '
'; document.getElementById('fwControls').style.display = 'block'; if (status.enabled) { document.getElementById('fwEnableBtn').style.display = 'none'; document.getElementById('fwEnabledBadge').style.display = 'inline-block'; if (status.rules && status.rules.length > 0) { let html = '
已开放端口:
'; document.getElementById('fwRulesList').innerHTML = html; } } else { document.getElementById('fwEnableBtn').style.display = 'inline-block'; document.getElementById('fwEnabledBadge').style.display = 'none'; } } else { document.getElementById('fwStatus').innerHTML = '
防火墙状态加载失败: ' + (fw.msg || '') + '
'; } const port = await api('/panel/port'); if (port.code === 0) { document.getElementById('curPanelPort').value = port.data.port; } await loadBackupSettings(); await loadBackupList(); } async function enableFirewall() { if (!confirm('确定启用防火墙?将自动开放 22/80/443/8888 端口。')) return; const d = await api('/firewall/enable', { method: 'POST' }); alert(d.msg); loadProduction(); } async function openPort() { const port = document.getElementById('fwPort').value.trim(); const proto = document.getElementById('fwProto').value; if (!port) { alert('请输入端口号'); return; } const d = await api('/firewall/port', { method: 'POST', body: JSON.stringify({ port: port, proto: proto, action: 'open' }) }); alert(d.msg); if (d.code === 0) { document.getElementById('fwPort').value = ''; loadProduction(); } } async function closePort(port) { if (!confirm('确定关闭端口 ' + port + '?')) return; const d = await api('/firewall/port', { method: 'POST', body: JSON.stringify({ port: port, proto: 'tcp', action: 'close' }) }); alert(d.msg); loadProduction(); } async function changePanelPort() { const newPort = document.getElementById('newPanelPort').value.trim(); if (!newPort) { alert('请输入新端口'); return; } if (!confirm('确定将面板端口修改为 ' + newPort + '?修改后需要使用新端口重新访问!')) return; const d = await api('/panel/port', { method: 'POST', body: JSON.stringify({ port: newPort }) }); alert(d.msg); if (d.code === 0) { setTimeout(() => { window.location.href = window.location.protocol + '//' + window.location.hostname + ':' + newPort; }, 2000); } } async function loadBackupSettings() { const d = await api('/backup/settings'); if (d.code === 0) { const s = d.data; document.getElementById('backupEnabled').value = s.enabled ? '1' : '0'; document.getElementById('backupSchedule').value = s.schedule || 'daily'; document.getElementById('backupKeepDays').value = s.keep_days || 7; document.getElementById('backupDir').value = s.backup_dir || '/backup'; } } async function saveBackupSettings() { const enabled = document.getElementById('backupEnabled').value === '1'; const schedule = document.getElementById('backupSchedule').value; const keepDays = document.getElementById('backupKeepDays').value; const backupDir = document.getElementById('backupDir').value.trim(); const d = await api('/backup/settings', { method: 'POST', body: JSON.stringify({ enabled: enabled, schedule: schedule, keep_days: keepDays, backup_dir: backupDir }) }); alert(d.msg); loadBackupSettings(); } async function runBackupNow() { if (!confirm('确定立即执行一次备份?')) return; const d = await api('/backup/run', { method: 'POST' }); alert(d.msg); setTimeout(loadBackupList, 3000); } async function loadBackupList() { const d = await api('/backup/list'); if (d.code === 0) { const data = d.data; let html = '
备份目录:' + data.backup_dir + ' | 总大小:' + data.total_size + '
'; html += '

📁 站点备份

'; if (data.sites.length === 0) { html += '
暂无备份
'; } else { data.sites.forEach(f => { html += '
' + f.name + ' (' + f.size + ')
'; }); } html += '
'; html += '

🗄️ 数据库备份

'; if (data.databases.length === 0) { html += '
暂无备份
'; } else { data.databases.forEach(f => { html += '
' + f.name + ' (' + f.size + ')
'; }); } html += '
'; document.getElementById('backupList').innerHTML = html; } } async function deleteBackup(type, filename) { if (!confirm('确定删除备份 ' + filename + '?')) return; const d = await api('/backup/delete', { method: 'POST', body: JSON.stringify({ type: type, filename: filename }) }); alert(d.msg); loadBackupList(); } checkAuth();