# Docker CSS Compilation Fix

## Problem Description

The frontend was completely broken in Docker/production environments - pages displayed as plain unstyled text without any CSS styling.

### Root Cause

The `.dockerignore` file in `apps/frontend/` was excluding critical Tailwind CSS configuration files:
- `postcss.config.js`
- `tailwind.config.js`
- `tailwind.config.ts`

This prevented PostCSS and Tailwind CSS from compiling the CSS during Docker builds. The CSS file contained raw `@tailwind base;@tailwind components;@tailwind utilities;` directives instead of the compiled CSS.

### Why It Worked Locally

Local development (`npm run dev` or `npm run build`) worked fine because:
- Config files were present on the filesystem
- Tailwind JIT compiler could process the directives
- The compiled CSS output was ~60KB of actual CSS rules

### Why It Failed in Docker

Docker builds failed because:
- `.dockerignore` excluded the config files from the build context
- Next.js build couldn't find `postcss.config.js` or `tailwind.config.ts`
- CSS compilation was skipped entirely
- The raw source CSS file was copied as-is (containing `@tailwind` directives)
- Browsers couldn't interpret the `@tailwind` directives

## Solution

### 1. Frontend `.dockerignore` Fix

**File**: `apps/frontend/.dockerignore`

```diff
 # Other
 .prettierrc
 .prettierignore
 .eslintrc.json
 .eslintignore
-postcss.config.js
-tailwind.config.js
+# postcss.config.js  # NEEDED for Tailwind CSS compilation
+# tailwind.config.js # NEEDED for Tailwind CSS compilation
+# tailwind.config.ts # NEEDED for Tailwind CSS compilation
 next-env.d.ts
 tsconfig.tsbuildinfo
```

**Impact**: This fix applies to:
- ✅ Local Docker builds (`docker-compose.dev.yml`)
- ✅ CI/CD builds (GitHub Actions `.github/workflows/ci.yml`)
- ✅ Production deployments (Portainer pulls from CI/CD registry)

### 2. Additional Docker Fixes

While fixing the CSS issue, we also resolved:

#### Backend Docker Permissions
- **Problem**: CSV file uploads failed with `EACCES: permission denied, mkdir '/app/apps'`
- **Solution**:
  - Copy `src/` directory to production Docker image
  - Create `/app/src/infrastructure/storage/csv-storage/rates` with proper ownership
  - Add `getCsvUploadPath()` helper for Docker/dev path resolution

#### Port Conflicts for Local Testing
- **Problem**: Backend couldn't start because port 4000 was already in use
- **Solution**:
  - Map to different ports in `docker-compose.dev.yml`
  - Backend: `4001:4000` instead of `4000:4000`
  - Frontend: `3001:3000` instead of `3000:3000`
  - Updated `CORS_ORIGIN` and `NEXT_PUBLIC_API_URL` accordingly

## How to Verify the Fix

### Local Docker Testing (Mac ARM64)

```bash
# Build and start all services
docker compose -f docker-compose.dev.yml up -d --build

# Wait for frontend to be ready
docker compose -f docker-compose.dev.yml ps

# Check CSS is compiled (should show compiled CSS, not @tailwind directives)
docker exec xpeditis-frontend-dev find .next/static/css -name "*.css" -exec head -c 200 {} \;

# Expected output:
# *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0...
# (NOT: @tailwind base;@tailwind components;@tailwind utilities;)
```

**Access Points**:
- Frontend: http://localhost:3001 (should show fully styled pages)
- Backend API: http://localhost:4001
- MinIO Console: http://localhost:9001 (minioadmin/minioadmin)

### Production Deployment (Scaleway + Portainer)

1. **Push to preprod branch** (triggers CI/CD):
   ```bash
   git push origin preprod
   ```

2. **Monitor GitHub Actions**:
   - Go to: https://github.com/YOUR_ORG/xpeditis/actions
   - Wait for "CI/CD Pipeline" to complete
   - Verify frontend build shows: `✓ Compiled successfully`

3. **Verify Docker Registry**:
   ```bash
   # Pull the newly built image
   docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod

   # Inspect the image
   docker run --rm --entrypoint sh rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod -c \
     "find .next/static/css -name '*.css' -exec head -c 200 {} \;"
   ```

4. **Deploy via Portainer**:
   - Go to Portainer: https://portainer.preprod.xpeditis.com
   - Stacks → xpeditis-preprod → Update the stack
   - Click "Pull and redeploy"
   - Wait for frontend container to restart

5. **Test Production Frontend**:
   - Visit: https://app.preprod.xpeditis.com
   - **Expected**: Fully styled landing page with:
     - Navy blue hero section
     - Turquoise accent colors
     - Proper typography (Manrope/Montserrat fonts)
     - Gradient backgrounds
     - Animations and hover effects
   - **NOT Expected**: Plain black text on white background

### CSS Verification Script

```bash
#!/bin/bash
# Test CSS compilation in Docker container

CONTAINER_NAME="xpeditis-frontend-dev"

echo "🔍 Checking CSS files in container..."
CSS_CONTENT=$(docker exec $CONTAINER_NAME find .next/static/css -name "*.css" -exec head -c 100 {} \;)

if echo "$CSS_CONTENT" | grep -q "@tailwind"; then
  echo "❌ FAIL: CSS contains uncompiled @tailwind directives"
  echo "CSS content: $CSS_CONTENT"
  exit 1
elif echo "$CSS_CONTENT" | grep -q "tw-border-spacing"; then
  echo "✅ PASS: CSS is properly compiled with Tailwind"
  echo "CSS preview: $CSS_CONTENT"
  exit 0
else
  echo "⚠️  UNKNOWN: Unexpected CSS content"
  echo "CSS content: $CSS_CONTENT"
  exit 2
fi
```

## Technical Details

### Tailwind CSS Compilation Process

1. **Without config files** (broken):
   ```
   Source: app/globals.css
   ↓
   @tailwind base;
   @tailwind components;
   @tailwind utilities;
   ↓
   [NO PROCESSING - config files missing]
   ↓
   Output: Same raw directives (27KB)
   ↓
   Browser: ❌ Cannot interpret @tailwind directives
   ```

2. **With config files** (fixed):
   ```
   Source: app/globals.css
   ↓
   @tailwind base;
   @tailwind components;
   @tailwind utilities;
   ↓
   PostCSS + Tailwind JIT Compiler
   (using tailwind.config.ts + postcss.config.js)
   ↓
   Output: Compiled CSS (60KB+ of actual rules)
   ↓
   Browser: ✅ Fully styled page
   ```

### Docker Build Context

When Docker builds an image:
1. It reads `.dockerignore` to determine which files to exclude
2. It copies the remaining files into the build context
3. Next.js build runs `npm run build`
4. Next.js looks for `postcss.config.js` and `tailwind.config.ts`
5. If found: Tailwind compiles CSS ✅
6. If missing: Raw CSS copied as-is ❌

## Related Files

### Configuration Files (MUST be in Docker build context)
- ✅ `apps/frontend/postcss.config.js` - Tells Next.js to use Tailwind
- ✅ `apps/frontend/tailwind.config.ts` - Tailwind configuration
- ✅ `apps/frontend/app/globals.css` - Source CSS with @tailwind directives

### Build Files
- `apps/frontend/Dockerfile` - Frontend Docker build
- `apps/frontend/.dockerignore` - **CRITICAL: Must not exclude config files**
- `.github/workflows/ci.yml` - CI/CD pipeline (uses apps/frontend context)
- `docker/portainer-stack.yml` - Production deployment stack

### Testing Files
- `docker-compose.dev.yml` - Local testing stack (Mac ARM64)

## Lessons Learned

1. **Never exclude build tool configs from Docker**:
   - PostCSS/Tailwind configs must be in build context
   - Same applies to `.babelrc`, `tsconfig.json`, etc.
   - Only exclude generated output, not source configs

2. **Always verify CSS compilation in Docker**:
   - Check actual CSS content, not just "build succeeded"
   - Compare file sizes (27KB raw vs 60KB compiled)
   - Test in a real browser, not just curl

3. **Docker build ≠ Local build**:
   - Local `node_modules/` has all files
   - Docker only has files not in `.dockerignore`
   - Always test Docker builds locally before deploying

## Commit Reference

- **Commit**: `88f0cc9` - fix: enable Tailwind CSS compilation in Docker builds
- **Branch**: `preprod`
- **Date**: 2025-11-19
- **Files Changed**:
  - `apps/frontend/.dockerignore`
  - `apps/backend/Dockerfile`
  - `apps/backend/src/application/controllers/admin/csv-rates.controller.ts`
  - `docker-compose.dev.yml`

## Rollback Plan

If this fix causes issues in production:

```bash
# Revert the commit
git revert 88f0cc9

# Or manually restore .dockerignore
git show 2505a36:apps/frontend/.dockerignore > apps/frontend/.dockerignore

# Push to trigger rebuild
git push origin preprod
```

**Note**: This would restore the broken CSS, so only do this if the fix causes new issues.

## Future Improvements

1. **Add CSS compilation check to CI/CD**:
   ```yaml
   - name: Verify CSS compilation
     run: |
       docker run --rm $IMAGE_NAME sh -c \
         "find .next/static/css -name '*.css' -exec grep -q '@tailwind' {} \; && exit 1 || exit 0"
   ```

2. **Document required Docker build context files**:
   - Create `apps/frontend/DOCKER_REQUIRED_FILES.md`
   - List all files needed for successful builds

3. **Add frontend healthcheck that verifies CSS**:
   - Create `/api/health/css` endpoint
   - Check that CSS files are properly compiled
   - Fail container startup if CSS is broken
