chore: update backup configurations and directory structure

- Modified `.gitignore` to exclude all files in the `/data/` directory.
- Enhanced `BACKUP.md` with customization options for backup storage paths and updated database path configurations.
- Updated `docker-compose.yml` to reflect new paths for database and backup storage.
- Adjusted `Dockerfile` to create a dedicated backups directory.
- Refactored `BackupService` to utilize environment variables for backup paths, improving flexibility and reliability.
- Deleted `dev.db` as it is no longer needed in the repository.
This commit is contained in:
Julien Froidefond
2025-09-20 15:45:56 +02:00
parent dfa8d34855
commit 329018161c
10 changed files with 529 additions and 39 deletions

View File

@@ -31,11 +31,23 @@ export class BackupService {
enabled: true,
interval: 'hourly',
maxBackups: 5,
backupPath: path.join(process.cwd(), 'backups'),
backupPath: this.getDefaultBackupPath(),
includeUploads: true,
compression: true,
};
private getDefaultBackupPath(): string {
// 1. Variable d'environnement explicite
if (process.env.BACKUP_STORAGE_PATH) {
return path.resolve(process.cwd(), process.env.BACKUP_STORAGE_PATH);
}
// 2. Chemin par défaut selon l'environnement
return process.env.NODE_ENV === 'production'
? path.join(process.cwd(), 'data', 'backups') // Docker: /app/data/backups
: path.join(process.cwd(), 'backups'); // Local: ./backups
}
private config: BackupConfig;
constructor(config?: Partial<BackupConfig>) {
@@ -106,10 +118,7 @@ export class BackupService {
// Créer le dossier de backup si nécessaire
await this.ensureBackupDirectory();
// Vérifier l'état de la base de données
await this.verifyDatabaseHealth();
// Créer la sauvegarde SQLite
// Créer la sauvegarde SQLite (sans vérification de santé pour éviter les conflits)
await this.createSQLiteBackup(backupPath);
// Compresser si activé
@@ -156,7 +165,26 @@ export class BackupService {
* Crée une sauvegarde SQLite en utilisant la commande .backup
*/
private async createSQLiteBackup(backupPath: string): Promise<void> {
const dbPath = path.resolve(process.env.DATABASE_URL?.replace('file:', '') || './prisma/dev.db');
// Résoudre le chemin de la base de données
let dbPath: string;
if (process.env.BACKUP_DATABASE_PATH) {
// Utiliser la variable spécifique aux backups
dbPath = path.resolve(process.cwd(), process.env.BACKUP_DATABASE_PATH);
} else if (process.env.DATABASE_URL) {
// Fallback sur DATABASE_URL si BACKUP_DATABASE_PATH n'est pas défini
dbPath = path.resolve(process.env.DATABASE_URL.replace('file:', ''));
} else {
// Chemin par défaut vers prisma/dev.db
dbPath = path.resolve(process.cwd(), 'prisma', 'dev.db');
}
// Vérifier que le fichier source existe
try {
await fs.stat(dbPath);
} catch (error) {
console.error(`❌ Source database not found: ${dbPath}`, error);
throw new Error(`Source database not found: ${dbPath}`);
}
// Méthode 1: Utiliser sqlite3 CLI (plus fiable)
try {
@@ -199,7 +227,19 @@ export class BackupService {
*/
async restoreBackup(filename: string): Promise<void> {
const backupPath = path.join(this.config.backupPath, filename);
const dbPath = path.resolve(process.env.DATABASE_URL?.replace('file:', '') || './prisma/dev.db');
// Résoudre le chemin de la base de données
let dbPath: string;
if (process.env.BACKUP_DATABASE_PATH) {
// Utiliser la variable spécifique aux backups
dbPath = path.resolve(process.cwd(), process.env.BACKUP_DATABASE_PATH);
} else if (process.env.DATABASE_URL) {
// Fallback sur DATABASE_URL si BACKUP_DATABASE_PATH n'est pas défini
dbPath = path.resolve(process.env.DATABASE_URL.replace('file:', ''));
} else {
// Chemin par défaut vers prisma/dev.db
dbPath = path.resolve(process.cwd(), 'prisma', 'dev.db');
}
console.log(`🔄 Restore paths - backup: ${backupPath}, target: ${dbPath}`);