# Docker Setup Guide

This project is now containerized with Docker. Below are instructions for building and running the application in Docker.

## Quick Start

### Production

```bash
docker-compose up -d app
# Visit http://localhost
```

### Staging

```bash
docker-compose --profile staging up -d staging
# Visit http://localhost:8080
```

### Development

```bash
docker-compose --profile dev up dev
# Visit http://localhost:4200
```

## Prerequisites

- Docker installed (version 20.10+)
- Docker Compose installed (version 2.0+)

## Production Build

### Build the Docker Image

```bash
docker build -t psp_panel:latest .
```

### Run the Container

```bash
docker run -d -p 80:80 --name psp_panel psp_panel:latest
```

The application will be available at `http://localhost`

### Run with Docker Compose

```bash
docker-compose up -d app
```

## Staging Build

### Build for Staging

```bash
docker build -f Dockerfile.staging -t psp_panel:staging .
```

### Run Staging Container

```bash
docker run -d -p 8080:80 --name psp_panel-staging psp_panel:staging
```

### Run with Docker Compose

```bash
docker-compose --profile staging up -d staging
```

The application will be available at `http://localhost:8080`

## Development Mode

### Using Docker

For development with hot reload, use the `dev` profile:

```bash
docker-compose --profile dev up dev
```

The application will be available at `http://localhost:4200`

### Building Development Image Directly

```bash
docker build -f Dockerfile.dev -t psp_panel:dev .
docker run -it -v $(pwd):/app -p 4200:4200 psp_panel:dev
```

## Environment Variables

To use specific environment configurations, you can build with different targets. Currently, the Dockerfile builds for production. To build for staging:

### Build for Staging

Create a separate `Dockerfile.staging` if needed, or manually use:

```bash
docker run -e NODE_ENV=staging psp_panel:latest
```

## Common Commands

### Docker Compose Commands

```bash
# Start production
docker-compose up -d app

# Start staging
docker-compose --profile staging up -d staging

# Start development
docker-compose --profile dev up dev

# Start all services
docker-compose --profile staging --profile dev up -d

# Stop services
docker-compose down

# View logs
docker-compose logs -f app         # Production logs
docker-compose logs -f staging     # Staging logs
docker-compose logs -f dev         # Development logs

# Rebuild images
docker-compose build --no-cache
```

### Docker CLI Commands

```bash
# View Logs

# Production
docker logs psp_panel

# Staging
docker logs psp_panel-staging

# Development
docker logs psp_panel-dev

# Stop Container

# Production
docker stop psp_panel
docker rm psp_panel

# Staging
docker stop psp_panel-staging
docker rm psp_panel-staging

# Development
docker stop psp_panel-dev
docker rm psp_panel-dev

# List running containers
docker ps

# List all containers
docker ps -a
```

### Clean Up

```bash
# Remove stopped containers
docker container prune

# Remove unused images
docker image prune

# Remove everything (careful!)
docker system prune -a
```

## Image Size Optimization

The Docker setup uses a multi-stage build:
1. **Builder stage**: Compiles the Angular application
2. **Production stage**: Uses nginx to serve the compiled application

This approach keeps the final image small (typically <50MB) by excluding build dependencies.

## Nginx Configuration

The `nginx.conf` file includes:
- Gzip compression for better performance
- Security headers (X-Frame-Options, X-Content-Type-Options, etc.)
- Proper caching headers for static assets
- Angular routing support (SPA routing)

## Port Configuration

- **Production**: Port 80
- **Development**: Port 4200

To use different ports:

```bash
docker run -d -p 8080:80 psp_panel:latest
# App available at http://localhost:8080
```

## Building for Different Environments

This project includes specialized Dockerfiles for different environments:

### Production

```bash
docker build -t psp_panel:prod .
docker run -d -p 80:80 psp_panel:prod
```

**Dockerfile**: `Dockerfile`
**Base Image**: `nginx:alpine`
**Configuration**: Production optimized build

### Staging

```bash
docker build -f Dockerfile.staging -t psp_panel:staging .
docker run -d -p 8080:80 psp_panel:staging
```

**Dockerfile**: `Dockerfile.staging`
**Base Image**: `nginx:alpine`
**Configuration**: Staging configuration with debugging enabled
**Port**: 8080

### Development

```bash
docker build -f Dockerfile.dev -t psp_panel:dev .
docker run -it -v $(pwd):/app -p 4200:4200 psp_panel:dev
```

**Dockerfile**: `Dockerfile.dev`
**Base Image**: `node:20-alpine`
**Features**: Hot reload, source maps, development server
**Port**: 4200
**Volume**: Mounts current directory for live updates

## Security Notes

- The production image is minimal and only contains what's necessary to run the application
- Security headers are configured in nginx
- Health checks are built in to ensure container availability
- Update base images regularly: `docker pull nginx:alpine` and `docker pull node:20-alpine`

## Troubleshooting

### Container exits immediately

Check logs for errors:
```bash
docker logs psp_panel
```

### Port already in use

Use a different port:
```bash
docker run -d -p 8080:80 psp_panel:latest
```

### Build fails on pnpm install

Ensure `pnpm-lock.yaml` is up to date:
```bash
pnpm install --frozen-lockfile
```

## CI/CD Integration

### GitHub Actions Example

```yaml
name: Build and Push Docker Image

on:
  push:
    branches: [main, staging]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Build Docker image
        run: |
          if [ "${{ github.ref }}" = "refs/heads/staging" ]; then
            docker build -f Dockerfile.staging -t psp_panel:staging .
          else
            docker build -t psp_panel:latest .
          fi

      - name: Push to registry
        run: |
          docker tag psp_panel:latest your-registry/psp_panel:latest
          docker push your-registry/psp_panel:latest
```

### Generic CI/CD

```bash
#!/bin/bash
BUILD_ID=${CI_COMMIT_SHA:0:8}
REGISTRY=${DOCKER_REGISTRY:-docker.io}

# Build
docker build -t $REGISTRY/psp_panel:$BUILD_ID .

# Test (optional)
docker run --rm $REGISTRY/psp_panel:$BUILD_ID wget --spider http://localhost

# Push
docker push $REGISTRY/psp_panel:$BUILD_ID

# Tag as latest
docker tag $REGISTRY/psp_panel:$BUILD_ID $REGISTRY/psp_panel:latest
docker push $REGISTRY/psp_panel:latest
```

## References

- [Docker Documentation](https://docs.docker.com/)
- [Nginx Documentation](https://nginx.org/)
- [Angular Deployment Guide](https://angular.io/guide/build)
