feat: Add Docker Compose configurations for Kvrocks and Redis deployments

- 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.
This commit is contained in:
katelya
2025-09-04 17:55:23 +08:00
parent 63120d418b
commit 82485d1939
20 changed files with 1943 additions and 154 deletions
+301
View File
@@ -0,0 +1,301 @@
#!/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;
}
}
// 检查1Docker 部署配置
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(', ')}`);
}
}
}
// 检查2Cloudflare 部署配置
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', '可能缺少部分配置');
}
}
}
// 检查3Vercel 部署配置
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', '文件不存在');
}
}
}
// 检查5package.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', '文件不存在或格式错误');
}
}
// 检查6Kvrocks 配置文件
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);