diff --git a/backend/src/server.ts b/backend/src/server.ts index d76034f..28397f4 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -39,26 +39,53 @@ app.get('/api/health', (req: any, res: any) => { }); }); -// πŸ†• STATIC FILE SERVING FÜR FRONTEND -const frontendBuildPath = process.env.FRONTEND_BUILD_PATH || '../frontend-build'; +// πŸ†• FIXED STATIC FILE SERVING +// Use absolute path that matches Docker container structure +const frontendBuildPath = path.resolve('/app/frontend-build'); console.log('πŸ“ Frontend build path:', frontendBuildPath); +console.log('πŸ“ Current __dirname:', __dirname); -// ÜberprΓΌfe ob das Verzeichnis existiert -if (fs.existsSync(frontendBuildPath)) { - console.log('βœ… Frontend build directory exists'); - const files = fs.readdirSync(frontendBuildPath); - console.log('πŸ“„ Files in frontend-build:', files); - +// Check multiple possible locations for frontend build +const possiblePaths = [ + '/app/frontend-build', // Docker production path + path.join(__dirname, '../../frontend-build'), // Relative from dist + path.join(process.cwd(), 'frontend-build'), // From current working directory +]; + +let actualFrontendPath = null; +for (const testPath of possiblePaths) { + if (fs.existsSync(testPath)) { + actualFrontendPath = testPath; + console.log('βœ… Found frontend build at:', testPath); + break; + } +} + +if (actualFrontendPath) { // Serviere statische Dateien - app.use(express.static(frontendBuildPath)); + app.use(express.static(actualFrontendPath)); + + // List files for debugging + try { + const files = fs.readdirSync(actualFrontendPath); + console.log('πŸ“„ Files in frontend-build:', files); + } catch (err) { + console.log('❌ Could not read frontend-build directory:', err); + } console.log('βœ… Static file serving configured'); } else { - console.log('❌ Frontend build directory NOT FOUND:', frontendBuildPath); + console.log('❌ Frontend build directory NOT FOUND in any location'); + console.log('❌ Checked paths:', possiblePaths); } +// Root route app.get('/', (req, res) => { - const indexPath = path.join(frontendBuildPath, 'index.html'); + if (!actualFrontendPath) { + return res.status(500).send('Frontend build not found'); + } + + const indexPath = path.join(actualFrontendPath, 'index.html'); console.log('πŸ“„ Serving index.html from:', indexPath); if (fs.existsSync(indexPath)) { @@ -69,19 +96,30 @@ app.get('/', (req, res) => { } }); +// Client-side routing fallback app.get('*', (req, res) => { // Ignoriere API Routes if (req.path.startsWith('/api/')) { return res.status(404).json({ error: 'API endpoint not found' }); } - const indexPath = path.join(frontendBuildPath, 'index.html'); - console.log('πŸ”„ Client-side routing for:', req.path, '-> index.html'); + if (!actualFrontendPath) { + return res.status(500).json({ error: 'Frontend application not available' }); + } + + const indexPath = path.join(actualFrontendPath, 'index.html'); + console.log('πŸ”„ Client-side routing for:', req.path, '->', indexPath); if (fs.existsSync(indexPath)) { - res.sendFile(indexPath); + // Use absolute path with res.sendFile + res.sendFile(indexPath, (err) => { + if (err) { + console.error('Error sending index.html:', err); + res.status(500).send('Error loading application'); + } + }); } else { - console.error('❌ index.html not found for client-side routing'); + console.error('❌ index.html not found for client-side routing at:', indexPath); res.status(404).json({ error: 'Frontend application not found' }); } }); diff --git a/docker-compose.yml b/docker-compose.yml index a1f08e8..ccf6cb5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,26 +1,14 @@ version: '3.8' services: - schichtplan: - build: - context: . - dockerfile: backend/Dockerfile + schichtplaner: + container_name: schichtplaner + image: ghcr.io/donpat1to/schichtenplaner:v1.0.0 ports: - - "3001:3001" - - "3000:3000" - environment: - - NODE_ENV=production - - DATABASE_URL=file:./prod.db - - JWT_SECRET=your-production-secret-key-change-this - - PYTHON_PATH=/usr/bin/python3 + - "3002:3002" volumes: - app_data:/app/data restart: unless-stopped - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3001/health"] - interval: 30s - timeout: 10s - retries: 3 volumes: app_data: \ No newline at end of file