Files
pastel-ui/DOCKER.md

237 lines
5.8 KiB
Markdown
Raw Normal View History

# 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!