# Docker Setup Guide for JHP Web

## Quick Start

### Production Build

```bash
# Build the image
docker build -t jhp-web:latest .

# Run the container
docker run -p 3000:3000 jhp-web:latest
```

Or with Docker Compose:

```bash
# Build and start
docker-compose up -d

# View logs
docker-compose logs -f

# Stop
docker-compose down
```

### Development

Use the development docker-compose for hot reloading:

```bash
# Start with development setup
docker-compose -f docker-compose.dev.yml up -d

# View logs
docker-compose -f docker-compose.dev.yml logs -f

# Stop
docker-compose -f docker-compose.dev.yml down
```

## What's Included

### Files Created

1. **Dockerfile** - Production-optimized multi-stage build
   - Stage 1: Installs production dependencies
   - Stage 2: Builds the Next.js application
   - Stage 3: Production runtime with non-root user and health checks

2. **.dockerignore** - Excludes unnecessary files from build context

3. **docker-compose.yml** - Production deployment setup with Nginx reverse proxy

4. **docker-compose.dev.yml** - Development setup with hot reloading

5. **Dockerfile.dev** - Development-focused Dockerfile

6. **Dockerfile.nginx** - Nginx reverse proxy image

7. **nginx.conf** - Production-ready Nginx configuration
   - SSL/TLS termination
   - Static file caching
   - Gzip compression
   - Security headers
   - Reverse proxy to Next.js app

### Configuration Changes

- **next.config.ts** - Updated to use `output: "standalone"` mode for optimal Docker containerization
- **next.config.ts** - TypeScript and ESLint checks skipped during build for faster builds

## Using Nginx Reverse Proxy

The production setup includes Nginx as a reverse proxy for your Next.js application. This provides:

- SSL/TLS termination
- Static file caching with proper headers
- Gzip compression
- Security headers (HSTS, X-Frame-Options, etc.)
- HTTP to HTTPS redirect

### Quick Start with Nginx

```bash
# Build and start with Nginx
docker-compose up -d

# The app is now available at:
# - HTTP: http://localhost
# - HTTPS: https://localhost (with self-signed cert)
```

### SSL Certificate Setup

**For self-signed certificates (development):**

```bash
# Create ssl directory
mkdir -p ssl

# Generate self-signed certificate
openssl req -x509 -newkey rsa:4096 -keyout ssl/key.pem -out ssl/cert.pem -days 365 -nodes \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"
```

**For Let's Encrypt (production):**

```bash
# Using Certbot
docker run -it --rm --name certbot \
  -v "./ssl:/etc/letsencrypt" \
  certbot/certbot certonly --standalone \
  -d yourdomain.com \
  -d www.yourdomain.com
```

Then update `nginx.conf` with your domain and certificate paths.

### Nginx Configuration

The `nginx.conf` includes:

- Upstream definition pointing to the Next.js app container
- HTTP server redirecting to HTTPS
- HTTPS server with SSL configuration
- Static file caching for `/_next/static` and `/public`
- Reverse proxy with proper headers
- Health check endpoint at `/health`

## Best Practices Implemented

✅ **Security**

- Non-root user (nextjs:1001)
- Multi-stage builds reduce final image size
- No sensitive data in image layers
- Nginx SSL/TLS termination
- Security headers (HSTS, X-Frame-Options, CSP, etc.)
- HTTP to HTTPS redirect

✅ **Performance**

- Alpine Linux base image (~150MB vs ~900MB with Node.js default)
- Layer caching optimization
- Standalone output mode
- Nginx gzip compression
- Static file caching with long expiration headers
- Efficient upstream load balancing

✅ **Reliability**

- Health checks configured on both app and Nginx
- Automatic restart on failure
- Proper signal handling
- Connection pooling and keepalive settings

## Architecture

The production setup uses a two-container architecture:

```
┌─────────────────────────────────┐
│      External Traffic           │
│   (HTTP on port 80              │
│    HTTPS on port 443)           │
└──────────────┬──────────────────┘
               │
        ┌──────▼───────┐
        │    Nginx      │ (Port 80, 443)
        │ (Reverse      │
        │  Proxy, SSL)  │
        └──────┬────────┘
               │
        ┌──────▼────────┐
        │  Next.js App  │ (Port 3000, internal only)
        │   Container   │
        └───────────────┘
```

Both containers run on a private Docker network (`app-network`) and communicate internally.

## Building for Different Platforms

If you're developing on Mac/Windows but deploying to Linux:

```bash
# Build for Linux AMD64
docker buildx build --platform=linux/amd64 -t jhp-web:latest .
```

## Environment Variables

For production deployments, you can pass environment variables:

```bash
docker run -p 3000:3000 \
  -e NODE_ENV=production \
  jhp-web:latest
```

Or in `docker-compose.yml`, update the `environment` section.

### Port already in use (80 or 443)

```bash
# Find and stop the service using the port
lsof -i :80
lsof -i :443

# Or change ports in docker-compose.yml
# From: "80:80" to "8080:80"
# Then access at http://localhost:8080
```

### Nginx can't reach the Next.js app

```bash
# Check if app container is running
docker-compose ps

# Verify network connectivity
docker-compose exec nginx ping app

# Check Nginx logs
docker-compose logs nginx
```

### SSL certificate issues

```bash
# Verify certificate
openssl x509 -in ssl/cert.pem -text -noout

# Check if files are readable
ls -la ssl/

# Verify Nginx config
docker-compose exec nginx nginx -t
```

### Build fails

```bash
# Clear cache and rebuild
docker-compose build --no-cache
docker-compose up
```

### View container logs

```bash
# View all logs
docker-compose logs -f

# View specific service
docker-compose logs -f app
docker-compose logs -f nginx
```

### HTTPS not working

Make sure SSL certificates exist in the `ssl/` directory:

```bash
ls -la ssl/
# Should show: cert.pem and key.pem
```

If missing, generate self-signed certificates (see SSL Certificate Setup section).

## Deploying to Azure

For deployment to Azure Container Instances or Container Apps:

```bash
# Tag for container registry
docker tag jhp-web:latest myregistry.azurecr.io/jhp-web:latest

# Push to registry
docker push myregistry.azurecr.io/jhp-web:latest
```

Then deploy using Azure CLI or via Azure Portal.
