10 KiB
Docker Setup Summary
Completed Tasks
All Docker setup tasks have been successfully completed for the Feuerwehr Dashboard project.
Files Created
1. Backend Dockerfile
Location: /Users/matthias/work/feuerwehr_dashboard/backend/Dockerfile
- Multi-stage build (builder + production)
- Base image: node:20-alpine
- Build stage: Installs deps, compiles TypeScript
- Production stage: Only production deps, non-root user
- Copies migrations folder to dist/
- Health check: wget localhost:3000/health
- Exposes port 3000
- CMD: node dist/server.js
- Lines: 69
2. Backend .dockerignore
Location: /Users/matthias/work/feuerwehr_dashboard/backend/.dockerignore
- Excludes node_modules, dist, .env, logs
- Excludes IDE files, git files, documentation
- Optimizes build context size
3. Frontend Dockerfile
Location: /Users/matthias/work/feuerwehr_dashboard/frontend/Dockerfile
- Multi-stage build (builder + nginx)
- Builder: node:20-alpine, runs Vite build
- Production: nginx:alpine, serves static assets
- Build arguments: VITE_API_URL, VITE_APP_NAME, VITE_APP_VERSION
- Non-root nginx user
- Health check: wget localhost:80/health
- Exposes port 80
- CMD: nginx -g "daemon off;"
- Lines: 68
4. Frontend .dockerignore
Location: /Users/matthias/work/feuerwehr_dashboard/frontend/.dockerignore
- Excludes node_modules, dist, .env
- Excludes IDE files, git files, documentation
- Optimizes build context size
5. Nginx Configuration
Location: /Users/matthias/work/feuerwehr_dashboard/frontend/nginx.conf
- SPA routing: try_files with fallback to index.html
- Gzip compression enabled
- Static assets cached for 1 year
- index.html not cached
- Security headers:
- X-Frame-Options: SAMEORIGIN
- X-Content-Type-Options: nosniff
- X-XSS-Protection: 1; mode=block
- Referrer-Policy: strict-origin-when-cross-origin
- Health check endpoint: /health
- Custom error pages
- Lines: 99
6. Updated docker-compose.yml
Location: /Users/matthias/work/feuerwehr_dashboard/docker-compose.yml
- Fixed backend PORT environment variable (hardcoded to 3000)
- Fixed backend port mapping (maps to container port 3000)
- Fixed health check URL (uses container port 3000)
- All services have proper health checks
- Proper depends_on with health conditions
- Volume for postgres data persistence
- Bridge network for service communication
- Restart policies: unless-stopped
7. Docker Test Script
Location: /Users/matthias/work/feuerwehr_dashboard/docker-test.sh
- Checks Docker availability
- Tests backend image build
- Tests frontend image build
- Reports image sizes
- Option to cleanup test images
- Provides next steps
- Lines: 250
- Executable: Yes
8. Docker Validation Script
Location: /Users/matthias/work/feuerwehr_dashboard/docker-validate.sh
- Validates all Docker files exist
- Checks file permissions
- Reports missing files
- Executable: Yes
9. Docker Setup Documentation
Location: /Users/matthias/work/feuerwehr_dashboard/DOCKER_SETUP.md
- Comprehensive Docker setup guide
- Architecture overview
- Build instructions
- Security considerations
- Troubleshooting guide
- Production deployment guide
Docker Build Status
Note: Docker is not available on this system, so builds could not be tested automatically.
To Test Builds
When Docker is available, run:
cd /Users/matthias/work/feuerwehr_dashboard
./docker-test.sh
This will:
- Verify Docker is running
- Build backend image (tag: feuerwehr-backend-test:latest)
- Build frontend image (tag: feuerwehr-frontend-test:latest)
- Report image sizes
- Optionally cleanup test images
Manual Build Testing
Backend
cd /Users/matthias/work/feuerwehr_dashboard/backend
docker build -t feuerwehr-backend:latest .
Expected size: ~150-200 MB
Frontend
cd /Users/matthias/work/feuerwehr_dashboard/frontend
docker build \
--build-arg VITE_API_URL=http://localhost:3000 \
--build-arg VITE_APP_NAME="Feuerwehr Dashboard" \
--build-arg VITE_APP_VERSION="1.0.0" \
-t feuerwehr-frontend:latest .
Expected size: ~50-80 MB
Docker Compose Services
PostgreSQL
- Image: postgres:16-alpine
- Port: 5432
- Volume: postgres_data_prod (persistent)
- Health check: pg_isready
- Restart: unless-stopped
Backend
- Build: ./backend
- Port: 3000
- Depends on: postgres (healthy)
- Health check: wget localhost:3000/health
- Restart: unless-stopped
Frontend
- Build: ./frontend
- Port: 80
- Depends on: backend (healthy)
- Health check: wget localhost:80/health
- Restart: unless-stopped
Environment Variables
Create .env file based on .env.example:
Required Variables
POSTGRES_PASSWORD=your_secure_password
JWT_SECRET=your_jwt_secret_min_32_chars
Optional Variables (with defaults)
POSTGRES_DB=feuerwehr_prod
POSTGRES_USER=prod_user
POSTGRES_PORT=5432
BACKEND_PORT=3000
FRONTEND_PORT=80
CORS_ORIGIN=http://localhost:80
VITE_API_URL=http://localhost:3000
Quick Start Guide
1. Validate Setup
cd /Users/matthias/work/feuerwehr_dashboard
./docker-validate.sh
2. Configure Environment
cp .env.example .env
# Edit .env and set POSTGRES_PASSWORD and JWT_SECRET
3. Test Builds (Optional)
./docker-test.sh
4. Start Services
docker-compose up -d
5. Check Status
docker-compose ps
docker-compose logs -f
6. Access Application
- Frontend: http://localhost:80
- Backend: http://localhost:3000
- Database: localhost:5432
Security Features
Backend
- Non-root user execution (nodejs:1001)
- Alpine Linux base (minimal attack surface)
- Only production dependencies
- No source code in final image
- Health checks enabled
- wget installed for monitoring
Frontend
- Non-root nginx execution
- Alpine Linux base
- Security headers configured
- Static assets only in final image
- Gzip compression
- Proper cache headers
- Health checks enabled
Image Optimization
Multi-Stage Builds
- Separate build and production stages
- Smaller final images
- No build tools in production
Layer Caching
- Package files copied first
- Dependencies installed before source
- Optimized build times
.dockerignore
- Excludes unnecessary files
- Reduces build context
- Faster builds
Health Checks
All services include Docker health checks:
PostgreSQL
- Interval: 10s
- Retries: 5
- Start period: 10s
Backend
- Endpoint: /health
- Interval: 30s
- Retries: 3
- Start period: 40s
Frontend
- Endpoint: /health
- Interval: 30s
- Retries: 3
- Start period: 30s
Production Considerations
Before Deployment
- Set strong POSTGRES_PASSWORD (min 16 chars)
- Set strong JWT_SECRET (min 32 chars)
- Configure CORS_ORIGIN to production domain
- Set VITE_API_URL to production API URL
- Enable HTTPS/SSL
- Configure firewall rules
- Set up monitoring
- Configure backup strategy
Resource Limits
Consider adding resource limits in docker-compose.yml:
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
Monitoring
# View container stats
docker stats
# View logs
docker-compose logs -f
# Check health
docker-compose ps
Troubleshooting
Build Fails
-
Check Docker is running:
docker info -
View build output:
docker-compose build --no-cache -
Check individual service:
cd backend # or frontend docker build -t test .
Container Won't Start
-
Check logs:
docker-compose logs [service] -
Check health:
docker-compose ps -
Verify environment:
docker-compose config
Database Connection Issues
-
Verify postgres is healthy:
docker-compose ps postgres -
Check DATABASE_URL format:
postgresql://user:password@postgres:5432/database -
Test connection:
docker-compose exec backend ping postgres
Next Steps
-
Install Docker (if not already installed)
- macOS: Docker Desktop for Mac
- Linux: Docker Engine
- Windows: Docker Desktop for Windows
-
Test Docker Setup
./docker-test.sh -
Configure Environment
- Copy .env.example to .env
- Set required variables
-
Deploy Application
docker-compose up -d -
Monitor Services
docker-compose logs -f docker-compose ps
Additional Resources
- Docker Setup Documentation - Comprehensive guide
- Backend Dockerfile - Backend image definition
- Frontend Dockerfile - Frontend image definition
- Nginx Config - Web server configuration
- Docker Compose - Service orchestration
File Locations
All files are in the project root: /Users/matthias/work/feuerwehr_dashboard/
/Users/matthias/work/feuerwehr_dashboard/
├── backend/
│ ├── Dockerfile # Backend image (69 lines)
│ └── .dockerignore # Backend ignore rules
├── frontend/
│ ├── Dockerfile # Frontend image (68 lines)
│ ├── nginx.conf # Nginx config (99 lines)
│ └── .dockerignore # Frontend ignore rules
├── docker-compose.yml # Service orchestration (updated)
├── docker-test.sh # Build test script (250 lines)
├── docker-validate.sh # Validation script
├── DOCKER_SETUP.md # Comprehensive documentation
└── SUMMARY.md # This file
Validation Results
All Docker files have been validated:
✓ backend/Dockerfile exists
✓ backend/.dockerignore exists
✓ frontend/Dockerfile exists
✓ frontend/.dockerignore exists
✓ frontend/nginx.conf exists
✓ docker-compose.yml exists
✓ docker-test.sh exists and is executable
Summary
The production-ready Docker setup is complete with:
- Multi-stage builds for optimized image sizes
- Security best practices (non-root users, Alpine base)
- Health checks for all services
- Layer caching optimization
- SPA routing with Nginx
- Gzip compression and cache headers
- Security headers configured
- Test scripts for validation
- Comprehensive documentation
The application is ready for Docker deployment once Docker is installed and environment variables are configured.