fix: Resolve backend permission errors for temp and logs directories
- Fix MinIO service temp directory path (was going to /temp instead of /app/temp) - Add TEMP_DIR environment variable support - Make audit logger optional in development mode to avoid permission issues - Ensure log directory exists before creating loggers - Update docker-entrypoint.sh to create temp directory - Create backend/temp directory with .gitkeep - Update .gitignore to exclude temp files but keep directory structure This fixes the EACCES permission errors that were causing the backend to restart. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,8 @@ coverage/
|
||||
temp/
|
||||
tmp/
|
||||
*.tmp
|
||||
backend/temp/*
|
||||
!backend/temp/.gitkeep
|
||||
|
||||
# MinIO configuration
|
||||
.mc/
|
||||
|
||||
@@ -6,5 +6,10 @@ if [ ! -d "/app/logs" ]; then
|
||||
mkdir -p /app/logs
|
||||
fi
|
||||
|
||||
# Ensure temp directory exists
|
||||
if [ ! -d "/app/temp" ]; then
|
||||
mkdir -p /app/temp
|
||||
fi
|
||||
|
||||
# Start the application
|
||||
exec node src/app.js
|
||||
@@ -12,7 +12,7 @@ const execAsync = util.promisify(exec);
|
||||
class MinIOService {
|
||||
constructor(alias = config.minio.defaultAlias) {
|
||||
this.alias = alias;
|
||||
this.tempDir = path.join(__dirname, '../../../temp');
|
||||
this.tempDir = process.env.TEMP_DIR || path.join(__dirname, '../../temp');
|
||||
this.ensureTempDir();
|
||||
}
|
||||
|
||||
|
||||
+38
-14
@@ -1,10 +1,20 @@
|
||||
const winston = require('winston');
|
||||
const DailyRotateFile = require('winston-daily-rotate-file');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const config = require('../config');
|
||||
|
||||
const logDir = process.env.LOG_DIR || path.join(__dirname, '../../logs');
|
||||
|
||||
// Ensure log directory exists
|
||||
try {
|
||||
if (!fs.existsSync(logDir)) {
|
||||
fs.mkdirSync(logDir, { recursive: true });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to create log directory:', error);
|
||||
}
|
||||
|
||||
// Define log format
|
||||
const logFormat = winston.format.combine(
|
||||
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
||||
@@ -72,22 +82,30 @@ const logger = winston.createLogger({
|
||||
});
|
||||
|
||||
// Create audit logger for security events
|
||||
const auditLogger = winston.createLogger({
|
||||
level: 'info',
|
||||
format: logFormat,
|
||||
transports: [
|
||||
new DailyRotateFile({
|
||||
filename: path.join(logDir, 'audit-%DATE%.log'),
|
||||
datePattern: 'YYYY-MM-DD',
|
||||
maxSize: '20m',
|
||||
maxFiles: '90d',
|
||||
})
|
||||
],
|
||||
});
|
||||
let auditLogger;
|
||||
if (config.app.env === 'production') {
|
||||
auditLogger = winston.createLogger({
|
||||
level: 'info',
|
||||
format: logFormat,
|
||||
transports: [
|
||||
new DailyRotateFile({
|
||||
filename: path.join(logDir, 'audit-%DATE%.log'),
|
||||
datePattern: 'YYYY-MM-DD',
|
||||
maxSize: '20m',
|
||||
maxFiles: '90d',
|
||||
})
|
||||
],
|
||||
exitOnError: false,
|
||||
});
|
||||
} else {
|
||||
// In development, just use the main logger for audit events
|
||||
auditLogger = logger;
|
||||
}
|
||||
|
||||
// Helper function for audit logging
|
||||
const logAudit = (action, { userId, ip, resource, status, details = {} }) => {
|
||||
auditLogger.info({
|
||||
const auditEntry = {
|
||||
audit: true,
|
||||
action,
|
||||
userId,
|
||||
ip,
|
||||
@@ -95,7 +113,13 @@ const logAudit = (action, { userId, ip, resource, status, details = {} }) => {
|
||||
status,
|
||||
details,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
};
|
||||
|
||||
if (config.app.env === 'production') {
|
||||
auditLogger.info(auditEntry);
|
||||
} else {
|
||||
logger.info('AUDIT:', auditEntry);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
||||
Reference in New Issue
Block a user