# Docker Deployment Guide ## Runtime Configuration This application uses a **Next.js API proxy** pattern to allow runtime configuration without rebuilding the Docker image. ### How It Works 1. **Client** makes requests to `/api/pastel/*` 2. **Next.js API Route** (`app/api/pastel/[...path]/route.ts`) proxies requests to the backend 3. **Backend API URL** is read from `PASTEL_API_URL` environment variable at runtime This means you can change the backend API URL by simply restarting the container with a different environment variable - **no rebuild required!** ## Quick Start ### Using Docker Compose ```bash # Start both UI and API docker-compose up -d # The UI will automatically connect to the API container # (configured via PASTEL_API_URL=http://pastel-api:3001) ``` ### Using Docker Run ```bash # Build the image once docker build -t pastel-ui . # Run with default settings (expects API at http://localhost:3001) docker run -p 3000:3000 pastel-ui # Run with custom API URL (no rebuild needed!) docker run -p 3000:3000 \ -e PASTEL_API_URL=http://my-api-server:3001 \ pastel-ui # Run with external API docker run -p 3000:3000 \ -e PASTEL_API_URL=https://api.example.com \ pastel-ui ``` ## Environment Variables ### Server-Side (Runtime Configuration) | Variable | Description | Default | Example | |----------|-------------|---------|---------| | `PASTEL_API_URL` | Backend API URL | `http://localhost:3001` | `http://pastel-api:3001` | | `NODE_ENV` | Node environment | `production` | `production` | | `PORT` | Server port | `3000` | `3000` | **Important:** These can be changed at runtime without rebuilding the image! ## Configuration Examples ### Docker Compose with Custom API ```yaml # docker-compose.yml services: pastel-ui: image: ghcr.io/valknarness/pastel-ui:latest ports: - "3000:3000" environment: - PASTEL_API_URL=http://my-custom-api:8080 ``` ### Docker Compose with External API ```yaml services: pastel-ui: image: ghcr.io/valknarness/pastel-ui:latest ports: - "3000:3000" environment: - PASTEL_API_URL=https://api.pastel.example.com ``` ### Using .env File ```bash # .env PASTEL_API_URL=http://pastel-api:3001 # docker-compose.yml will automatically read this docker-compose up -d ``` ## Local Development ```bash # Install dependencies pnpm install # Create .env.local file cat > .env.local << EOF PASTEL_API_URL=http://localhost:3001 EOF # Start development server pnpm dev # Open http://localhost:3000 ``` ## Building ```bash # Build the Docker image docker build -t pastel-ui . # No build arguments needed - configuration is runtime! ``` ## Health Checks The container includes health checks using curl: ```bash # Check container health docker inspect --format='{{.State.Health.Status}}' pastel-ui # Manual health check curl http://localhost:3000/ ``` ## Troubleshooting ### API Connection Issues **Problem:** Cannot connect to Pastel API **Solutions:** 1. **Check API URL:** ```bash docker exec pastel-ui env | grep PASTEL_API_URL ``` 2. **Test API connectivity from container:** ```bash docker exec pastel-ui curl -f ${PASTEL_API_URL}/api/v1/health ``` 3. **Check Docker network:** ```bash docker network inspect pastel-network ``` 4. **Update API URL without rebuild:** ```bash docker-compose down # Edit .env file docker-compose up -d ``` ### CORS Issues If you see CORS errors, the API proxy automatically adds CORS headers. Make sure: - The `PASTEL_API_URL` is accessible from the container - The API service is running - Network connectivity exists between containers ### Container Logs ```bash # View logs docker-compose logs -f pastel-ui # View API proxy logs specifically docker-compose logs -f pastel-ui | grep -i proxy ``` ## Architecture ``` ┌──────────────┐ │ Browser │ └──────┬───────┘ │ fetch('/api/pastel/colors/info') ▼ ┌──────────────────────────────────┐ │ Next.js Container (port 3000) │ │ │ │ ┌────────────────────────────┐ │ │ │ API Proxy Route │ │ │ │ /api/pastel/[...path] │ │ │ │ │ │ │ │ Reads: PASTEL_API_URL │ │ │ │ (runtime env var) │ │ │ └────────────┬───────────────┘ │ └───────────────┼───────────────────┘ │ proxy request ▼ ┌──────────────────────────────────┐ │ Pastel API (port 3001) │ │ /api/v1/colors/info │ └──────────────────────────────────┘ ``` ## Benefits of This Approach ✅ **No Rebuild Required** - Change API URL by restarting container ✅ **Environment Flexibility** - Same image works in dev/staging/prod ✅ **Network Isolation** - Backend API doesn't need public exposure ✅ **CORS Handled** - Proxy adds necessary CORS headers ✅ **Type Safety** - TypeScript client works seamlessly with proxy ## Migration from Old Approach If you were using `NEXT_PUBLIC_API_URL` before: **Old (Build-time):** ```dockerfile ARG NEXT_PUBLIC_API_URL ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} RUN pnpm build ``` **New (Runtime):** ```dockerfile # No build args needed RUN pnpm build # Runtime configuration via environment ENV PASTEL_API_URL=http://localhost:3001 ``` The new approach requires a rebuild to switch to the proxy pattern, but after that, no more rebuilds are needed for configuration changes!