From b079d35e3ab6ea659547e4a292c0b2fc8f7bfe10 Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Wed, 13 Aug 2025 21:03:48 +0000 Subject: [PATCH] Improve production stability by fixing backup directory permissions Adjust Dockerfile to create and grant permissions for backup directories, install PostgreSQL client for backups, and update BackupService to use the correct production backup path to resolve EACCES errors. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 7c468936-2a88-4686-ac0a-84921a45222d Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/7c468936-2a88-4686-ac0a-84921a45222d/K3Lzcje --- Dockerfile | 8 +- ...gs-Notific-1755118963207_1755118963207.txt | 228 ++++++++++++++++++ replit.md | 1 + server/backupService.ts | 33 ++- 4 files changed, 262 insertions(+), 8 deletions(-) create mode 100644 attached_assets/Pasted--Host-Administration-User-related-Environment-related-Registries-Logs-Notific-1755118963207_1755118963207.txt diff --git a/Dockerfile b/Dockerfile index 3b5b314..576f7a4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -84,8 +84,8 @@ COPY --from=build --chown=nextjs:nodejs /app/shared ./shared # Create symlink for public files to be accessible from dist RUN ln -sf /app/dist/public /app/dist/public -# Create uploads directory with proper permissions -RUN mkdir -p /app/uploads && chown -R nextjs:nodejs /app/uploads +# Create uploads and backups directories with proper permissions +RUN mkdir -p /app/uploads /app/backups && chown -R nextjs:nodejs /app/uploads /app/backups # Switch to non-root user USER nextjs @@ -94,9 +94,9 @@ USER nextjs EXPOSE 3000 ENV PORT=3000 -# Install wget for health check +# Install wget for health check and postgresql-client for pg_dump USER root -RUN apk add --no-cache wget +RUN apk add --no-cache wget postgresql-client USER nextjs # Health check diff --git a/attached_assets/Pasted--Host-Administration-User-related-Environment-related-Registries-Logs-Notific-1755118963207_1755118963207.txt b/attached_assets/Pasted--Host-Administration-User-related-Environment-related-Registries-Logs-Notific-1755118963207_1755118963207.txt new file mode 100644 index 0000000..d523f54 --- /dev/null +++ b/attached_assets/Pasted--Host-Administration-User-related-Environment-related-Registries-Logs-Notific-1755118963207_1755118963207.txt @@ -0,0 +1,228 @@ + + +Host + +Administration + +User-related + + +Environment-related + +Registries + +Logs + +Notifications + +Settings + +New version available 2.27.9 +DismissSee what's new +Community Edition +2.27.6 LTS +Containers>logiflow-logiflow-1>Logs +Container logs + + +admin +Log viewer settings +Auto-refresh logs +Wrap lines +Display timestamps +Fetch +All logs +Search +Filter... +Lines +100 +Actions + + + + + path: '/app/backups' + +} + +Node.js v20.19.4 + +🔗 Database initialization: { + + NODE_ENV: 'production', + + isProduction: true, + + hasDbUrl: true, + + dbHost: 'logiflow-db' + +} + +🐳 PRODUCTION: Using standard PostgreSQL + +✅ PostgreSQL connection test successful + +🔗 Database initialization: { + + NODE_ENV: 'production', + + isProduction: true, + + hasDbUrl: true, + + dbHost: 'logiflow-db:5432' + +} + +✅ Using DatabaseStorage (production PostgreSQL) + + node:fs:1372 + + const result = binding.mkdir( + + ^ + +Error: EACCES: permission denied, mkdir '/app/backups' + + at Object.mkdirSync (node:fs:1372:26) + + at BackupService.ensureBackupDirectory (file:///app/dist/index.js:3147:10) + + at new BackupService (file:///app/dist/index.js:3142:10) + + at file:///app/dist/index.js:3283:21 + + at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { + + errno: -13, + + code: 'EACCES', + + syscall: 'mkdir', + + path: '/app/backups' + +} + +Node.js v20.19.4 + +🔗 Database initialization: { + + NODE_ENV: 'production', + + isProduction: true, + + hasDbUrl: true, + + dbHost: 'logiflow-db' + +} + +🐳 PRODUCTION: Using standard PostgreSQL + +✅ PostgreSQL connection test successful + +🔗 Database initialization: { + + NODE_ENV: 'production', + + isProduction: true, + + hasDbUrl: true, + + dbHost: 'logiflow-db:5432' + +} + +✅ Using DatabaseStorage (production PostgreSQL) + + node:fs:1372 + + const result = binding.mkdir( + + ^ + +Error: EACCES: permission denied, mkdir '/app/backups' + + at Object.mkdirSync (node:fs:1372:26) + + at BackupService.ensureBackupDirectory (file:///app/dist/index.js:3147:10) + + at new BackupService (file:///app/dist/index.js:3142:10) + + at file:///app/dist/index.js:3283:21 + + at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { + + errno: -13, + + code: 'EACCES', + + syscall: 'mkdir', + + path: '/app/backups' + +} + +Node.js v20.19.4 + +🔗 Database initialization: { + + NODE_ENV: 'production', + + isProduction: true, + + hasDbUrl: true, + + dbHost: 'logiflow-db' + +} + +🐳 PRODUCTION: Using standard PostgreSQL + +✅ PostgreSQL connection test successful + +🔗 Database initialization: { + + NODE_ENV: 'production', + + isProduction: true, + + hasDbUrl: true, + + dbHost: 'logiflow-db:5432' + +} + +✅ Using DatabaseStorage (production PostgreSQL) + + node:fs:1372 + + const result = binding.mkdir( + + ^ + +Error: EACCES: permission denied, mkdir '/app/backups' + + at Object.mkdirSync (node:fs:1372:26) + + at BackupService.ensureBackupDirectory (file:///app/dist/index.js:3147:10) + + at new BackupService (file:///app/dist/index.js:3142:10) + + at file:///app/dist/index.js:3283:21 + + at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { + + errno: -13, + + code: 'EACCES', + + syscall: 'mkdir', + + path: '/app/backups' + +} + +Node.js v20.19.4 \ No newline at end of file diff --git a/replit.md b/replit.md index eaa00fa..3f717b6 100644 --- a/replit.md +++ b/replit.md @@ -27,6 +27,7 @@ La plateforme fournit une gestion robuste des flux de travail de livraison avec - **Base de données** : Table `DATABASE_BACKUPS` avec suivi complet des sauvegardes - **Navigation** : Ajouté dans la sidebar administration pour les admins - **Compatibilité ESM** : Remplacement de `node-cron` par `setTimeout` natif pour résoudre l'erreur production +- **Permissions Docker** : Correction permissions `/app/backups` et installation `postgresql-client` pour `pg_dump` ### 2025-08-13 - Optimisation performance production + correction calendrier ✅ **Résolution latence production** : diff --git a/server/backupService.ts b/server/backupService.ts index d74f80b..b4f2170 100644 --- a/server/backupService.ts +++ b/server/backupService.ts @@ -15,15 +15,40 @@ export class BackupService { private maxBackups = 10; constructor() { - this.backupDir = path.join(process.cwd(), 'backups'); + // Use /app/backups in production (with proper permissions), or use env variable + const isProduction = process.env.NODE_ENV === 'production'; + this.backupDir = isProduction + ? process.env.BACKUP_DIR || '/app/backups' + : path.join(process.cwd(), 'backups'); + this.ensureBackupDirectory(); this.scheduleAutomaticBackup(); } private ensureBackupDirectory(): void { - if (!fs.existsSync(this.backupDir)) { - fs.mkdirSync(this.backupDir, { recursive: true }); - console.log('📁 Backup directory created:', this.backupDir); + try { + if (!fs.existsSync(this.backupDir)) { + fs.mkdirSync(this.backupDir, { recursive: true }); + console.log('📁 Backup directory created:', this.backupDir); + } + } catch (error) { + console.error('❌ Failed to create backup directory:', error); + // Fallback to /tmp if current directory fails + if (this.backupDir !== '/tmp/backups') { + this.backupDir = '/tmp/backups'; + console.log('🔄 Falling back to /tmp/backups'); + try { + if (!fs.existsSync(this.backupDir)) { + fs.mkdirSync(this.backupDir, { recursive: true }); + console.log('📁 Fallback backup directory created:', this.backupDir); + } + } catch (fallbackError) { + console.error('❌ Failed to create fallback directory:', fallbackError); + throw fallbackError; + } + } else { + throw error; + } } }