# Docker Compose Guide

This project provides two Docker Compose configurations for different use cases.

## Quick Start

### Using Pre-Built Images (Recommended)

Pull and run the latest images from the Gitea container registry:

```bash
# Copy environment template
cp .env.example .env

# Edit .env and set IMAGE_TAG (optional, defaults to 'dev')
# IMAGE_TAG=dev        # Development images (develop branch)
# IMAGE_TAG=latest     # Production images (main branch)
# IMAGE_TAG=658ec077   # Specific commit SHA

# Pull and start services
docker compose pull
docker compose up -d
```

**File:** `docker-compose.yml`

### Building Locally

Build all images locally (useful for development):

```bash
# Copy environment template
cp .env.example .env

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

**File:** `docker-compose.build.yml`

## Compose File Comparison

| File                       | Purpose               | Image Source                                      | When to Use                                       |
| -------------------------- | --------------------- | ------------------------------------------------- | ------------------------------------------------- |
| `docker-compose.yml`       | Pull pre-built images | `git.mosaicstack.dev/mosaic/stack-*:${IMAGE_TAG}` | Production, staging, testing with CI-built images |
| `docker-compose.build.yml` | Build locally         | Local Dockerfiles                                 | Active development, testing local changes         |

## Image Tags

The `IMAGE_TAG` environment variable controls which image version to pull:

- `dev` - Latest development build from `develop` branch (default)
- `latest` - Latest stable build from `main` branch
- `658ec077` - Specific commit SHA (first 8 characters)
- `v1.0.0` - Specific version tag

## Services Included

Both compose files include the same services:

**Core Stack:**

- `postgres` - PostgreSQL 17 with pgvector extension
- `valkey` - Redis-compatible cache
- `api` - Mosaic NestJS API
- `web` - Mosaic Next.js Web App
- `orchestrator` - Mosaic Agent Orchestrator

**Optional Services (via profiles):**

- `authentik-*` - OIDC authentication provider (profile: `authentik`)
- `ollama` - Local LLM service (profile: `ollama`)
- `traefik` - Reverse proxy (profile: `traefik-bundled`)

## Switching Between Modes

### From Local Build to Registry Images

```bash
# Stop current containers
docker compose -f docker-compose.build.yml down

# Switch to registry images
docker compose pull
docker compose up -d
```

### From Registry Images to Local Build

```bash
# Stop current containers
docker compose down

# Switch to local build
docker compose -f docker-compose.build.yml up -d --build
```

## CI/CD Pipeline

The Woodpecker CI pipeline automatically builds and pushes images to `git.mosaicstack.dev`:

- **Develop branch** → `stack-*:dev` + `stack-*:<commit-sha>`
- **Main branch** → `stack-*:latest` + `stack-*:<commit-sha>`
- **Tags** → `stack-*:v1.0.0` + `stack-*:<commit-sha>`

## Docker Registry Authentication

To pull images from the private Gitea registry, you need to authenticate:

```bash
# Login to Gitea registry
docker login git.mosaicstack.dev

# Enter your Gitea username and password
# Or use a Gitea access token as the password
```

To generate a Gitea access token:

1. Go to https://git.mosaicstack.dev/user/settings/applications
2. Create a new access token with `read:package` permission
3. Use your username and the token as your password

## Updating Images

### Update to Latest Dev Images

```bash
docker compose pull
docker compose up -d
```

### Update to Specific Version

```bash
# Set IMAGE_TAG in .env
echo "IMAGE_TAG=658ec077" >> .env

# Pull and restart
docker compose pull
docker compose up -d
```

## Troubleshooting

### "Image not found" errors

**Cause:** Registry authentication required or image doesn't exist

**Fix:**

```bash
# Login to registry
docker login git.mosaicstack.dev

# Verify image exists
docker search git.mosaicstack.dev/mosaic/stack-api

# Check available tags at:
# https://git.mosaicstack.dev/mosaic/-/packages
```

### Build failures with docker-compose.build.yml

**Cause:** Missing dependencies or build context

**Fix:**

```bash
# Ensure you're in the project root
cd /path/to/mosaic-stack

# Install dependencies first
pnpm install

# Build with verbose output
docker compose -f docker-compose.build.yml build --progress=plain
```

### Services fail to start

**Cause:** Environment variables not set

**Fix:**

```bash
# Copy environment template
cp .env.example .env

# Edit .env and replace all REPLACE_WITH_* placeholders
# Minimum required:
# - POSTGRES_PASSWORD
# - JWT_SECRET
# - BETTER_AUTH_SECRET
# - ENCRYPTION_KEY

# Restart services
docker compose up -d
```

## Example Configurations

The repository includes three example compose files for common deployment scenarios:

### Turnkey (All Bundled)

**File:** `docker/docker-compose.example.turnkey.yml`
**Use Case:** Local development, testing, demo environments

```bash
# Set in .env
COMPOSE_PROFILES=full
IMAGE_TAG=dev

# Start all services
docker compose up -d
```

All services run in Docker: PostgreSQL, Valkey, OpenBao, Authentik, Ollama.

### Production (All External)

**File:** `docker/docker-compose.example.external.yml`
**Use Case:** Production with managed services (AWS, GCP, Azure)

```bash
# Copy example file
cp docker/docker-compose.example.external.yml docker-compose.override.yml

# Edit .env with external service URLs
# COMPOSE_PROFILES=  # Empty
# DATABASE_URL=postgresql://...
# VALKEY_URL=redis://...
# etc.

# Start only API and Web
docker compose up -d
```

Uses external managed services for all infrastructure.

### Hybrid (Mixed)

**File:** `docker/docker-compose.example.hybrid.yml`
**Use Case:** Staging environments, gradual migration

```bash
# Copy example file
cp docker/docker-compose.example.hybrid.yml docker-compose.override.yml

# Set in .env
COMPOSE_PROFILES=database,cache,ollama
# ... external service URLs for auth/secrets

# Start mixed deployment
docker compose up -d
```

Bundles database/cache/AI locally, uses external auth/secrets.

## See Also

- [Docker Swarm Deployment](../docs/SWARM-DEPLOYMENT.md) - Production deployment with Docker Swarm
- [Swarm Quick Reference](../docs/SWARM-QUICKREF.md) - Common swarm commands
- [Configuration Guide](../docs/CONFIGURATION.md) - Environment variable reference
- [OpenBao Documentation](../docs/OPENBAO.md) - Secrets management setup
