82485d1939
- Implemented `docker-compose.kvrocks.auth.yml` for Kvrocks with password authentication. - Created `docker-compose.redis.yml` for Redis deployment. - Added Kvrocks configuration file `kvrocks.auth.conf` with necessary settings. - Updated documentation with deployment guidelines for Kvrocks. - Introduced ESLint configuration for code quality. - Developed deployment configuration check script `check-deployment-configs.js`. - Added D1 database initialization script `d1-init.sql` for KatelyaTV. - Created test script `test-kvrocks-deployment.js` to validate Kvrocks deployment. - Implemented fix verification script `verify-kvrocks-fix.js` for password handling. - Updated `wrangler.toml` for Cloudflare deployment configuration.
302 lines
8.4 KiB
JavaScript
302 lines
8.4 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
/**
|
||
* KatelyaTV 全方案部署状态检查脚本
|
||
* 检查所有部署方案的配置文件和环境是否完整
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
console.log('🔍 KatelyaTV 部署配置检查开始...\n');
|
||
|
||
// 检查结果统计
|
||
let checkResults = {
|
||
total: 0,
|
||
passed: 0,
|
||
failed: 0,
|
||
warnings: 0,
|
||
errors: []
|
||
};
|
||
|
||
// 辅助函数
|
||
function logCheck(name, status, message = '') {
|
||
checkResults.total++;
|
||
if (status === 'PASS') {
|
||
checkResults.passed++;
|
||
console.log(`✅ ${name}: PASS ${message}`);
|
||
} else if (status === 'WARN') {
|
||
checkResults.warnings++;
|
||
console.log(`⚠️ ${name}: WARN ${message}`);
|
||
} else {
|
||
checkResults.failed++;
|
||
console.log(`❌ ${name}: FAIL ${message}`);
|
||
checkResults.errors.push(`${name}: ${message}`);
|
||
}
|
||
}
|
||
|
||
function fileExists(filePath) {
|
||
try {
|
||
return fs.existsSync(filePath);
|
||
} catch (error) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function readJsonFile(filePath) {
|
||
try {
|
||
const content = fs.readFileSync(filePath, 'utf8');
|
||
return JSON.parse(content);
|
||
} catch (error) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 检查1:Docker 部署配置
|
||
function checkDockerConfigs() {
|
||
console.log('🐳 检查 Docker 部署配置...');
|
||
|
||
const dockerConfigs = [
|
||
{
|
||
name: 'Docker + Redis 配置',
|
||
files: ['docker-compose.redis.yml', '.env.redis.example']
|
||
},
|
||
{
|
||
name: 'Docker + Kvrocks 配置(无密码)',
|
||
files: ['docker-compose.kvrocks.yml', '.env.kvrocks.example']
|
||
},
|
||
{
|
||
name: 'Docker + Kvrocks 配置(密码认证)',
|
||
files: ['docker-compose.kvrocks.auth.yml']
|
||
},
|
||
{
|
||
name: 'Docker + Kvrocks 本地构建配置',
|
||
files: ['docker-compose.kvrocks.local.yml']
|
||
}
|
||
];
|
||
|
||
for (const config of dockerConfigs) {
|
||
let allFilesExist = true;
|
||
let missingFiles = [];
|
||
|
||
for (const file of config.files) {
|
||
if (!fileExists(file)) {
|
||
allFilesExist = false;
|
||
missingFiles.push(file);
|
||
}
|
||
}
|
||
|
||
if (allFilesExist) {
|
||
logCheck(config.name, 'PASS', '所有配置文件存在');
|
||
} else {
|
||
logCheck(config.name, 'FAIL', `缺失文件: ${missingFiles.join(', ')}`);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查2:Cloudflare 部署配置
|
||
function checkCloudflareConfigs() {
|
||
console.log('\n☁️ 检查 Cloudflare 部署配置...');
|
||
|
||
const cloudflareFiles = [
|
||
'wrangler.toml',
|
||
'.env.cloudflare.example',
|
||
'scripts/d1-init.sql'
|
||
];
|
||
|
||
for (const file of cloudflareFiles) {
|
||
if (fileExists(file)) {
|
||
logCheck(`Cloudflare 配置文件 ${file}`, 'PASS', '文件存在');
|
||
} else {
|
||
logCheck(`Cloudflare 配置文件 ${file}`, 'FAIL', '文件不存在');
|
||
}
|
||
}
|
||
|
||
// 检查 wrangler.toml 内容
|
||
if (fileExists('wrangler.toml')) {
|
||
const content = fs.readFileSync('wrangler.toml', 'utf8');
|
||
if (content.includes('d1_databases') && content.includes('pages:build')) {
|
||
logCheck('wrangler.toml 内容', 'PASS', '包含必要配置');
|
||
} else {
|
||
logCheck('wrangler.toml 内容', 'WARN', '可能缺少部分配置');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查3:Vercel 部署配置
|
||
function checkVercelConfigs() {
|
||
console.log('\n▲ 检查 Vercel 部署配置...');
|
||
|
||
const vercelFile = 'vercel.json';
|
||
if (fileExists(vercelFile)) {
|
||
logCheck('Vercel 配置文件', 'PASS', 'vercel.json 存在');
|
||
|
||
const vercelConfig = readJsonFile(vercelFile);
|
||
if (vercelConfig) {
|
||
if (vercelConfig.build && vercelConfig.build.env) {
|
||
logCheck('Vercel 构建配置', 'PASS', '包含环境变量配置');
|
||
} else {
|
||
logCheck('Vercel 构建配置', 'WARN', '可能缺少构建环境配置');
|
||
}
|
||
}
|
||
} else {
|
||
logCheck('Vercel 配置文件', 'FAIL', 'vercel.json 不存在');
|
||
}
|
||
}
|
||
|
||
// 检查4:环境变量示例文件
|
||
function checkEnvExamples() {
|
||
console.log('\n⚙️ 检查环境变量示例文件...');
|
||
|
||
const envFiles = [
|
||
'.env.example',
|
||
'.env.redis.example',
|
||
'.env.kvrocks.example',
|
||
'.env.cloudflare.example'
|
||
];
|
||
|
||
for (const envFile of envFiles) {
|
||
if (fileExists(envFile)) {
|
||
const content = fs.readFileSync(envFile, 'utf8');
|
||
const hasStorageType = content.includes('NEXT_PUBLIC_STORAGE_TYPE');
|
||
const hasAuthConfig = content.includes('NEXTAUTH_SECRET');
|
||
|
||
if (hasStorageType && hasAuthConfig) {
|
||
logCheck(`环境变量文件 ${envFile}`, 'PASS', '包含必要配置');
|
||
} else {
|
||
logCheck(`环境变量文件 ${envFile}`, 'WARN', '可能缺少部分配置');
|
||
}
|
||
} else {
|
||
logCheck(`环境变量文件 ${envFile}`, 'FAIL', '文件不存在');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查5:package.json 脚本
|
||
function checkPackageScripts() {
|
||
console.log('\n📦 检查 package.json 构建脚本...');
|
||
|
||
const packageJson = readJsonFile('package.json');
|
||
if (packageJson && packageJson.scripts) {
|
||
const requiredScripts = [
|
||
'dev',
|
||
'build',
|
||
'start',
|
||
'pages:build', // Cloudflare Pages
|
||
'lint'
|
||
];
|
||
|
||
for (const script of requiredScripts) {
|
||
if (packageJson.scripts[script]) {
|
||
logCheck(`package.json 脚本 ${script}`, 'PASS', '脚本存在');
|
||
} else {
|
||
logCheck(`package.json 脚本 ${script}`, 'WARN', '脚本不存在或未配置');
|
||
}
|
||
}
|
||
} else {
|
||
logCheck('package.json', 'FAIL', '文件不存在或格式错误');
|
||
}
|
||
}
|
||
|
||
// 检查6:Kvrocks 配置文件
|
||
function checkKvrocksConfigs() {
|
||
console.log('\n🏪 检查 Kvrocks 配置文件...');
|
||
|
||
const kvrocksConfigs = [
|
||
'docker/kvrocks/kvrocks.conf',
|
||
'docker/kvrocks/kvrocks.auth.conf'
|
||
];
|
||
|
||
for (const configFile of kvrocksConfigs) {
|
||
if (fileExists(configFile)) {
|
||
const content = fs.readFileSync(configFile, 'utf8');
|
||
const hasBasicConfig = content.includes('bind') && content.includes('port');
|
||
|
||
if (hasBasicConfig) {
|
||
logCheck(`Kvrocks 配置 ${path.basename(configFile)}`, 'PASS', '包含基本配置');
|
||
} else {
|
||
logCheck(`Kvrocks 配置 ${path.basename(configFile)}`, 'WARN', '可能缺少基本配置');
|
||
}
|
||
} else {
|
||
logCheck(`Kvrocks 配置 ${path.basename(configFile)}`, 'FAIL', '文件不存在');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查7:文档文件
|
||
function checkDocumentation() {
|
||
console.log('\n📚 检查文档文件...');
|
||
|
||
const docFiles = [
|
||
'README.md',
|
||
'docs/KVROCKS.md',
|
||
'docs/KVROCKS_DEPLOYMENT.md',
|
||
'docs/TVBOX.md',
|
||
'KVROCKS_FIX_REPORT.md'
|
||
];
|
||
|
||
for (const docFile of docFiles) {
|
||
if (fileExists(docFile)) {
|
||
logCheck(`文档文件 ${docFile}`, 'PASS', '文件存在');
|
||
} else {
|
||
logCheck(`文档文件 ${docFile}`, 'WARN', '文件不存在');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 主检查函数
|
||
async function runChecks() {
|
||
try {
|
||
await checkDockerConfigs();
|
||
await checkCloudflareConfigs();
|
||
await checkVercelConfigs();
|
||
await checkEnvExamples();
|
||
await checkPackageScripts();
|
||
await checkKvrocksConfigs();
|
||
await checkDocumentation();
|
||
|
||
} catch (error) {
|
||
console.error('检查执行出错:', error);
|
||
checkResults.failed++;
|
||
checkResults.errors.push(`检查执行出错: ${error.message}`);
|
||
}
|
||
|
||
// 输出检查结果
|
||
console.log('\n' + '='.repeat(60));
|
||
console.log('📊 部署配置检查结果汇总:');
|
||
console.log(` 总计: ${checkResults.total} 项检查`);
|
||
console.log(` 通过: ${checkResults.passed} 项 ✅`);
|
||
console.log(` 警告: ${checkResults.warnings} 项 ⚠️`);
|
||
console.log(` 失败: ${checkResults.failed} 项 ❌`);
|
||
|
||
if (checkResults.failed > 0) {
|
||
console.log('\n🚨 失败的检查项:');
|
||
checkResults.errors.forEach((error, index) => {
|
||
console.log(` ${index + 1}. ${error}`);
|
||
});
|
||
}
|
||
|
||
if (checkResults.warnings > 0) {
|
||
console.log('\n⚠️ 警告说明:');
|
||
console.log(' - 警告项目不影响基本功能,但建议完善');
|
||
console.log(' - 可能影响特定部署方案或高级功能');
|
||
}
|
||
|
||
if (checkResults.failed === 0) {
|
||
console.log('\n🎉 所有必要配置文件检查通过!');
|
||
console.log(' 您可以选择以下任意部署方案:');
|
||
console.log(' 1. 🐳 Docker + Redis (docker-compose.redis.yml)');
|
||
console.log(' 2. 🏪 Docker + Kvrocks (docker-compose.kvrocks.yml)');
|
||
console.log(' 3. ☁️ Cloudflare Pages + D1 (wrangler.toml)');
|
||
console.log(' 4. ▲ Vercel + Upstash (vercel.json)');
|
||
}
|
||
|
||
console.log('='.repeat(60));
|
||
|
||
// 退出代码
|
||
process.exit(checkResults.failed > 0 ? 1 : 0);
|
||
}
|
||
|
||
// 运行检查
|
||
runChecks().catch(console.error);
|