# Docker Timezone Configuration Fix ## Problem Even after fixing the SQLite `datetime('now', 'localtime')` calls, notes posted at 10:00 still showed as 08:00 when running in Docker. ## Root Cause **Docker containers run in UTC timezone by default!** When using `datetime('now', 'localtime')` in SQLite: - On local Windows machine: Uses Windows timezone (Europe/Warsaw) → ✅ Correct - In Docker container: Uses container timezone (UTC) → ❌ Wrong by 2 hours Example: ``` User posts at 10:00 Poland time (UTC+2) ↓ Docker container thinks local time is 08:00 UTC ↓ SQLite datetime('now', 'localtime') stores: 08:00 ↓ Display shows: 08:00 (wrong!) ``` ## Solution Set the Docker container timezone to Europe/Warsaw ### 1. Updated Dockerfile (Production) ```dockerfile # Use Node.js 22.11.0 as the base image FROM node:22.11.0 # Set timezone to Europe/Warsaw (Polish timezone) ENV TZ=Europe/Warsaw RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # ... rest of Dockerfile ``` ### 2. Updated Dockerfile.dev (Development) ```dockerfile # Use Node.js 22.11.0 as the base image FROM node:22.11.0 # Set timezone to Europe/Warsaw (Polish timezone) ENV TZ=Europe/Warsaw RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # ... rest of Dockerfile ``` ### 3. Updated docker-compose.yml (Development) ```yaml environment: - NODE_ENV=development - TZ=Europe/Warsaw ``` ### 4. Updated docker-compose.prod.yml (Production) ```yaml environment: - NODE_ENV=production - TZ=Europe/Warsaw - NEXTAUTH_SECRET=... - NEXTAUTH_URL=... ``` ## How to Apply ### Option 1: Rebuild Docker Images ```bash # Stop containers docker-compose down # Rebuild images docker-compose build --no-cache # Start containers docker-compose up -d ``` ### Option 2: For Production Deployment ```bash # Pull latest code with fixes git pull # Rebuild production image docker-compose -f docker-compose.prod.yml build --no-cache # Restart docker-compose -f docker-compose.prod.yml up -d ``` ## Verification After rebuilding and restarting, verify timezone inside container: ```bash # Check timezone docker exec -it date # Should show: Sat Oct 4 19:00:00 CEST 2025 # Check Node.js sees correct timezone docker exec -it node -e "console.log(new Date().toLocaleString('pl-PL', {timeZone: 'Europe/Warsaw'}))" # Should show current Polish time # Check SQLite sees correct timezone docker exec -it node -e "const db = require('better-sqlite3')('./data/database.sqlite'); console.log(db.prepare(\"SELECT datetime('now', 'localtime')\").get());" # Should show current Polish time ``` ## Why This Works 1. **TZ Environment Variable**: Tells all processes (including Node.js and SQLite) what timezone to use 2. **Symlink /etc/localtime**: Updates system timezone for the entire container 3. **echo TZ > /etc/timezone**: Ensures the timezone persists Now when SQLite uses `datetime('now', 'localtime')`: - Container local time is 10:00 Poland time - SQLite stores: 10:00 - Display shows: 10:00 ✅ ## Important Notes 1. **Must rebuild images**: Just restarting containers is not enough - the timezone configuration is baked into the image 2. **All existing data**: Old notes will still show incorrect times (they were stored in UTC) 3. **New notes**: Will now display correctly 4. **DST handling**: Europe/Warsaw automatically handles Daylight Saving Time transitions ## Alternative Approach (Not Recommended) Instead of changing container timezone, you could: 1. Store everything in UTC (like audit logs do with ISO format) 2. Always convert on display But this requires more code changes and the current approach is simpler and more maintainable. ## Files Modified 1. `Dockerfile` - Added TZ configuration 2. `Dockerfile.dev` - Added TZ configuration 3. `docker-compose.yml` - Added TZ environment variable 4. `docker-compose.prod.yml` - Added TZ environment variable ## Testing Checklist After deployment: - [ ] Container shows correct date/time with `docker exec date` - [ ] Post a new note at known time (e.g., 10:30) - [ ] Verify note displays the same time (10:30) - [ ] Check both project notes and task notes - [ ] Verify audit logs still work correctly - [ ] Check task timestamps (date_started, date_completed)