mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-23 15:08:22 +02:00
Merge pull request #102 from R0m1k3/1.1
Improve production stability by fixing backup directory permissions
This commit is contained in:
4 files changed
+262
-8
No files matched your search
+4
-4
@@ -84,8 +84,8 @@ COPY --from=build --chown=nextjs:nodejs /app/shared ./shared
|
|||||||
# Create symlink for public files to be accessible from dist
|
# Create symlink for public files to be accessible from dist
|
||||||
RUN ln -sf /app/dist/public /app/dist/public
|
RUN ln -sf /app/dist/public /app/dist/public
|
||||||
|
|
||||||
# Create uploads directory with proper permissions
|
# Create uploads and backups directories with proper permissions
|
||||||
RUN mkdir -p /app/uploads && chown -R nextjs:nodejs /app/uploads
|
RUN mkdir -p /app/uploads /app/backups && chown -R nextjs:nodejs /app/uploads /app/backups
|
||||||
|
|
||||||
# Switch to non-root user
|
# Switch to non-root user
|
||||||
USER nextjs
|
USER nextjs
|
||||||
@@ -94,9 +94,9 @@ USER nextjs
|
|||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
ENV PORT=3000
|
ENV PORT=3000
|
||||||
|
|
||||||
# Install wget for health check
|
# Install wget for health check and postgresql-client for pg_dump
|
||||||
USER root
|
USER root
|
||||||
RUN apk add --no-cache wget
|
RUN apk add --no-cache wget postgresql-client
|
||||||
USER nextjs
|
USER nextjs
|
||||||
|
|
||||||
# Health check
|
# Health check
|
||||||
|
|||||||
+228
@@ -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
|
||||||
@@ -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
|
- **Base de données** : Table `DATABASE_BACKUPS` avec suivi complet des sauvegardes
|
||||||
- **Navigation** : Ajouté dans la sidebar administration pour les admins
|
- **Navigation** : Ajouté dans la sidebar administration pour les admins
|
||||||
- **Compatibilité ESM** : Remplacement de `node-cron` par `setTimeout` natif pour résoudre l'erreur production
|
- **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
|
### 2025-08-13 - Optimisation performance production + correction calendrier
|
||||||
✅ **Résolution latence production** :
|
✅ **Résolution latence production** :
|
||||||
|
|||||||
+29
-4
@@ -15,15 +15,40 @@ export class BackupService {
|
|||||||
private maxBackups = 10;
|
private maxBackups = 10;
|
||||||
|
|
||||||
constructor() {
|
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.ensureBackupDirectory();
|
||||||
this.scheduleAutomaticBackup();
|
this.scheduleAutomaticBackup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ensureBackupDirectory(): void {
|
private ensureBackupDirectory(): void {
|
||||||
if (!fs.existsSync(this.backupDir)) {
|
try {
|
||||||
fs.mkdirSync(this.backupDir, { recursive: true });
|
if (!fs.existsSync(this.backupDir)) {
|
||||||
console.log('📁 Backup directory created:', 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user