fix(db): goodizing creation db
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
# Production environment variables for KSPGUTI Schedule
|
# Production environment variables for KSPGUTI Schedule
|
||||||
|
|
||||||
|
# Database directory (where schedule-app.db will be stored)
|
||||||
|
DATABASE_DIR=/opt/kspguti-schedule
|
||||||
|
|
||||||
# Site URL - used for canonical links and sitemap (optional, defaults to https://schedule.itlxrd.space)
|
# Site URL - used for canonical links and sitemap (optional, defaults to https://schedule.itlxrd.space)
|
||||||
NEXT_PUBLIC_SITE_URL=https://schedule.itlxrd.space
|
NEXT_PUBLIC_SITE_URL=https://schedule.itlxrd.space
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ import type { AppSettings } from './settings-loader'
|
|||||||
function getDatabaseDir(): string {
|
function getDatabaseDir(): string {
|
||||||
// Если указан путь через переменную окружения, используем его
|
// Если указан путь через переменную окружения, используем его
|
||||||
if (process.env.DATABASE_DIR) {
|
if (process.env.DATABASE_DIR) {
|
||||||
|
console.log(`[Database] Using DATABASE_DIR from env: ${process.env.DATABASE_DIR}`)
|
||||||
return process.env.DATABASE_DIR
|
return process.env.DATABASE_DIR
|
||||||
}
|
}
|
||||||
|
|
||||||
// В production режиме (standalone) используем стандартный путь
|
// В production режиме (standalone) используем стандартный путь
|
||||||
const cwd = process.cwd()
|
const cwd = process.cwd()
|
||||||
|
console.log(`[Database] process.cwd(): ${cwd}`)
|
||||||
|
|
||||||
// Если мы в .next/standalone, поднимаемся на 2 уровня вверх к корню проекта
|
// Если мы в .next/standalone, поднимаемся на 2 уровня вверх к корню проекта
|
||||||
if (cwd.includes('.next/standalone')) {
|
if (cwd.includes('.next/standalone')) {
|
||||||
@@ -21,18 +23,23 @@ function getDatabaseDir(): string {
|
|||||||
// Нужно подняться до /opt/kspguti-schedule
|
// Нужно подняться до /opt/kspguti-schedule
|
||||||
const standaloneMatch = cwd.match(/^(.+?)\/\.next\/standalone/)
|
const standaloneMatch = cwd.match(/^(.+?)\/\.next\/standalone/)
|
||||||
if (standaloneMatch && standaloneMatch[1]) {
|
if (standaloneMatch && standaloneMatch[1]) {
|
||||||
|
console.log(`[Database] Detected standalone mode, using: ${standaloneMatch[1]}`)
|
||||||
return standaloneMatch[1]
|
return standaloneMatch[1]
|
||||||
}
|
}
|
||||||
// Альтернативный способ: подняться на 2 уровня вверх
|
// Альтернативный способ: подняться на 2 уровня вверх
|
||||||
return path.resolve(cwd, '..', '..')
|
const parentDir = path.resolve(cwd, '..', '..')
|
||||||
|
console.log(`[Database] Fallback to parent directory: ${parentDir}`)
|
||||||
|
return parentDir
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверяем стандартный путь для production
|
// Проверяем стандартный путь для production
|
||||||
if (fs.existsSync('/opt/kspguti-schedule')) {
|
if (fs.existsSync('/opt/kspguti-schedule')) {
|
||||||
|
console.log('[Database] Using /opt/kspguti-schedule')
|
||||||
return '/opt/kspguti-schedule'
|
return '/opt/kspguti-schedule'
|
||||||
}
|
}
|
||||||
|
|
||||||
// В development используем текущую директорию
|
// В development используем текущую директорию
|
||||||
|
console.log(`[Database] Using cwd: ${cwd}`)
|
||||||
return cwd
|
return cwd
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,10 +51,31 @@ const DEFAULT_PASSWORD = 'ksadmin'
|
|||||||
// Путь к старой базе данных (для миграции)
|
// Путь к старой базе данных (для миграции)
|
||||||
const OLD_DB_PATH = path.join(DATABASE_DIR, 'data', 'schedule-app.db')
|
const OLD_DB_PATH = path.join(DATABASE_DIR, 'data', 'schedule-app.db')
|
||||||
|
|
||||||
|
console.log(`[Database] DB_PATH: ${DB_PATH}`)
|
||||||
|
|
||||||
// Создаем директорию db, если её нет
|
// Создаем директорию db, если её нет
|
||||||
const dbDir = path.dirname(DB_PATH)
|
const dbDir = path.dirname(DB_PATH)
|
||||||
|
console.log(`[Database] dbDir: ${dbDir}`)
|
||||||
|
|
||||||
if (!fs.existsSync(dbDir)) {
|
if (!fs.existsSync(dbDir)) {
|
||||||
|
console.log(`[Database] Creating directory: ${dbDir}`)
|
||||||
|
try {
|
||||||
fs.mkdirSync(dbDir, { recursive: true })
|
fs.mkdirSync(dbDir, { recursive: true })
|
||||||
|
console.log(`[Database] Directory created successfully`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[Database] Failed to create directory ${dbDir}:`, error)
|
||||||
|
throw new Error(`Failed to create database directory: ${dbDir}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем, можем ли записывать в директорию
|
||||||
|
try {
|
||||||
|
const testFile = path.join(dbDir, '.write-test')
|
||||||
|
fs.writeFileSync(testFile, 'test')
|
||||||
|
fs.unlinkSync(testFile)
|
||||||
|
console.log('[Database] Directory is writable')
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[Database] Directory ${dbDir} is not writable:`, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Миграция базы данных из data/ в db/ (если старая база существует)
|
// Миграция базы данных из data/ в db/ (если старая база существует)
|
||||||
@@ -92,10 +120,26 @@ function getDatabase(): Database.Database {
|
|||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('[Database] Initializing database connection...')
|
||||||
|
console.log(`[Database] DB_PATH: ${DB_PATH}`)
|
||||||
|
console.log(`[Database] DB_PATH exists: ${fs.existsSync(DB_PATH)}`)
|
||||||
|
|
||||||
// Выполняем миграцию расположения базы данных перед открытием
|
// Выполняем миграцию расположения базы данных перед открытием
|
||||||
migrateDatabaseLocation()
|
migrateDatabaseLocation()
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('[Database] Opening database...')
|
||||||
db = new Database(DB_PATH)
|
db = new Database(DB_PATH)
|
||||||
|
console.log('[Database] Database opened successfully')
|
||||||
|
|
||||||
|
// Проверяем, можем ли записывать
|
||||||
|
try {
|
||||||
|
db.exec('SELECT 1')
|
||||||
|
console.log('[Database] Database is writable')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Database] Database is not writable:', error)
|
||||||
|
throw new Error('Database is not writable: ' + (error as Error).message)
|
||||||
|
}
|
||||||
|
|
||||||
// Применяем современные настройки SQLite
|
// Применяем современные настройки SQLite
|
||||||
db.pragma('journal_mode = WAL') // Write-Ahead Logging для лучшей производительности
|
db.pragma('journal_mode = WAL') // Write-Ahead Logging для лучшей производительности
|
||||||
@@ -106,12 +150,20 @@ function getDatabase(): Database.Database {
|
|||||||
db.pragma('mmap_size = 268435456') // Memory-mapped I/O (256MB)
|
db.pragma('mmap_size = 268435456') // Memory-mapped I/O (256MB)
|
||||||
db.pragma('cache_size = -64000') // Размер кеша в страницах (64MB)
|
db.pragma('cache_size = -64000') // Размер кеша в страницах (64MB)
|
||||||
|
|
||||||
|
console.log('[Database] SQLite pragmas applied')
|
||||||
|
|
||||||
// Создаем таблицы, если их нет
|
// Создаем таблицы, если их нет
|
||||||
initializeTables()
|
initializeTables()
|
||||||
|
|
||||||
// Выполняем миграцию данных из JSON, если БД пустая
|
// Выполняем миграцию данных из JSON, если БД пустая
|
||||||
migrateFromJSON()
|
migrateFromJSON()
|
||||||
|
|
||||||
|
console.log('[Database] Database initialization complete')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Database] Failed to initialize database:', error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ Group=www-data
|
|||||||
WorkingDirectory=/opt/kspguti-schedule/.next/standalone
|
WorkingDirectory=/opt/kspguti-schedule/.next/standalone
|
||||||
Environment=NODE_ENV=production
|
Environment=NODE_ENV=production
|
||||||
Environment=NEXT_TELEMETRY_DISABLED=1
|
Environment=NEXT_TELEMETRY_DISABLED=1
|
||||||
|
Environment=DATABASE_DIR=/opt/kspguti-schedule
|
||||||
Environment=PORT=3000
|
Environment=PORT=3000
|
||||||
Environment=HOSTNAME=0.0.0.0
|
Environment=HOSTNAME=0.0.0.0
|
||||||
# Uncomment and set your environment variables:
|
# Uncomment and set your environment variables:
|
||||||
|
|||||||
Reference in New Issue
Block a user