> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ccs.kaitran.ca/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker Deployment

> Run the CCS Dashboard in Docker with persistent configuration and automatic restarts

## Overview

Docker deployment allows you to:

* **Isolated environment** - Run CCS Dashboard in a container with all dependencies
* **Persistent configuration** - Keep your config, credentials, and CLI tools across restarts
* **Resource limits** - Control memory and CPU usage for production deployments
* **Easy deployment** - Deploy to any system with Docker installed
* **Pre-installed CLIs** - claude, gemini, grok, opencode, and ccs ready to use

## Architecture

```
┌─────────────────────────────────────────────────────┐
│ Docker Container (ccs-dashboard)                    │
│                                                      │
│  Port 3000 ──▶ CCS Dashboard Web UI                 │
│  Port 8317 ──▶ CLIProxy API (OAuth providers)       │
│                                                      │
│  Volumes:                                            │
│  • /home/node/.ccs      (CCS config, credentials)   │
│  • /home/node/.claude   (Claude sessions, logs)     │
│  • /home/node/.opencode (OpenCode config)           │
│  • /home/node/.grok-cli (Grok CLI config)           │
└─────────────────────────────────────────────────────┘
```

## Prerequisites

* Docker 20.10+ or Docker Desktop
* Docker Compose 2.0+ (optional, for compose setup)
* 1GB free disk space
* Ports 3000 and 8317 available

## Quick Start (Docker Run)

<Steps>
  <Step title="Build the Image">
    Clone the CCS repository and build the Docker image:

    ```bash theme={null}
    git clone https://github.com/kaitranntt/ccs.git
    cd ccs
    docker build -f docker/Dockerfile -t ccs-dashboard:latest .
    ```

    Build time: \~5-10 minutes (one-time operation).
  </Step>

  <Step title="Run the Container">
    Start the CCS Dashboard container:

    ```bash theme={null}
    docker run -d \
      --name ccs-dashboard \
      --restart unless-stopped \
      -p 3000:3000 \
      -p 8317:8317 \
      -e CCS_PORT=3000 \
      -v ccs_home:/home/node/.ccs \
      ccs-dashboard:latest
    ```

    **Note:** `--restart unless-stopped` ensures the container restarts on system reboot.
  </Step>

  <Step title="Access the Dashboard">
    Open your browser and navigate to:

    ```
    http://localhost:3000
    ```

    The CLIProxy API is available at `http://localhost:8317` (used by OAuth providers and Dashboard features).
  </Step>
</Steps>

## Docker Compose Setup

For production deployments, use Docker Compose for easier management.

<Steps>
  <Step title="Create .env File (Optional)">
    Create a `.env` file in the `docker/` directory to customize ports and configuration:

    ```bash theme={null}
    # Ports
    CCS_DASHBOARD_PORT=3000
    CCS_CLIPROXY_PORT=8317

    # CCS Configuration
    CCS_DEBUG=0
    NO_COLOR=0

    # Remote Proxy (optional)
    CCS_PROXY_HOST=
    CCS_PROXY_PORT=
    CCS_PROXY_PROTOCOL=https
    CCS_PROXY_AUTH_TOKEN=

    # Skip Options
    CCS_SKIP_PREFLIGHT=0
    CCS_WEBSEARCH_SKIP=0

    # Optional: legacy API key grace days after upgrades
    CCS_DOCKER_LEGACY_KEY_GRACE_DAYS=14

    # Optional: explicit one-time recovery for already-broken old-key clients
    CCS_DOCKER_RESTORE_LEGACY_API_KEY=0
    ```
  </Step>

  <Step title="Start with Compose">
    From the repository root:

    ```bash theme={null}
    docker-compose -f docker/docker-compose.yml up -d
    ```

    View logs:

    ```bash theme={null}
    docker-compose -f docker/docker-compose.yml logs -f
    ```
  </Step>

  <Step title="Stop the Service">
    ```bash theme={null}
    docker-compose -f docker/docker-compose.yml down
    ```

    To remove volumes (delete all config):

    ```bash theme={null}
    docker-compose -f docker/docker-compose.yml down -v
    ```
  </Step>
</Steps>

## CLIProxy API Key Rotation

New integrated Docker deployments generate per-install CLIProxy API and
management secrets when custom values are missing. Upgrades from older
deployments that used the historical `ccs-internal-managed` API key keep that
legacy key valid beside the new key for 14 days by default.
The `ccs docker up` banner shows only a masked key; use `show-key --full` when
you need to copy the complete value into downstream clients.

```bash theme={null}
# Show a masked key
ccs docker show-key

# Reveal the full key for updating clients
ccs docker show-key --full

# Remove the legacy key before the grace window expires
ccs docker finalize-key-rotation
```

Set `CCS_DOCKER_LEGACY_KEY_GRACE_DAYS=0` to disable the grace window, or use a
larger value when clients need more time to update.

If a previous upgrade already replaced the old key before the grace window was
available, run once with `CCS_DOCKER_RESTORE_LEGACY_API_KEY=1` to explicitly
restore temporary compatibility. CCS will not infer this from random-looking
custom keys.

## Environment Variables

Common CCS environment variables supported in Docker:

| Variable                     | Purpose                    | Default |
| ---------------------------- | -------------------------- | ------- |
| `CCS_PORT`                   | Dashboard HTTP port        | `3000`  |
| `CCS_DEBUG`                  | Enable verbose logging     | `0`     |
| `NO_COLOR`                   | Disable ANSI colors        | `0`     |
| `CCS_SKIP_PREFLIGHT`         | Skip API key validation    | `0`     |
| `CCS_WEBSEARCH_SKIP`         | Skip WebSearch integration | `0`     |
| `CCS_PROXY_HOST`             | Remote proxy hostname      | -       |
| `CCS_PROXY_PORT`             | Remote proxy port          | -       |
| `CCS_PROXY_PROTOCOL`         | `http` or `https`          | `https` |
| `CCS_PROXY_AUTH_TOKEN`       | Remote proxy auth token    | -       |
| `CCS_PROXY_TIMEOUT`          | Health check timeout (ms)  | `2000`  |
| `CCS_PROXY_FALLBACK_ENABLED` | Enable local fallback      | `true`  |
| `CCS_ALLOW_SELF_SIGNED`      | Accept self-signed certs   | `false` |

Example with environment variables:

```bash theme={null}
docker run -d \
  --name ccs-dashboard \
  --restart unless-stopped \
  -p 3000:3000 \
  -p 8317:8317 \
  -e CCS_PORT=3000 \
  -e CCS_DEBUG=1 \
  -e NO_COLOR=1 \
  -e CCS_PROXY_HOST="proxy.example.com" \
  -e CCS_PROXY_PORT=443 \
  -e CCS_PROXY_PROTOCOL="https" \
  -v ccs_home:/home/node/.ccs \
  ccs-dashboard:latest
```

## Persistent Storage

The container uses named volumes for persistent data:

| Volume          | Container Path         | Purpose                           |
| --------------- | ---------------------- | --------------------------------- |
| `ccs_home`      | `/home/node/.ccs`      | CCS config, credentials, profiles |
| `claude_home`   | `/home/node/.claude`   | Claude sessions, logs, todolists  |
| `opencode_home` | `/home/node/.opencode` | OpenCode configuration            |
| `grok_home`     | `/home/node/.grok-cli` | Grok CLI configuration            |

**Note:** Only `ccs_home` is required. Other volumes are optional (used if you run respective CLIs inside the container).

### Backup Configuration

```bash theme={null}
# Backup CCS config
docker run --rm -v ccs_home:/data -v $(pwd):/backup \
  ubuntu tar czf /backup/ccs-backup.tar.gz /data

# Restore CCS config
docker run --rm -v ccs_home:/data -v $(pwd):/backup \
  ubuntu tar xzf /backup/ccs-backup.tar.gz -C /
```

## Resource Limits

For production deployments, limit container resources to prevent overconsumption.

### Docker Run

```bash theme={null}
docker run -d \
  --name ccs-dashboard \
  --restart unless-stopped \
  --memory=1g \
  --cpus=2 \
  -p 3000:3000 \
  -p 8317:8317 \
  -v ccs_home:/home/node/.ccs \
  ccs-dashboard:latest
```

### Docker Compose

Default limits are set in `docker-compose.yml`:

```yaml theme={null}
deploy:
  resources:
    limits:
      memory: 1G
      cpus: '2'
    reservations:
      memory: 256M
      cpus: '0.5'
```

Adjust based on workload. Monitor usage with:

```bash theme={null}
docker stats ccs-dashboard
```

## Healthcheck

The container includes a healthcheck that verifies:

1. Dashboard HTTP server (port 3000)
2. CLIProxy API (port 8317)

```yaml theme={null}
healthcheck:
  test: ["CMD-SHELL", "curl -fsS --max-time 2 http://localhost:3000/ >/dev/null && curl -sS --max-time 2 http://127.0.0.1:8317/ >/dev/null"]
  interval: 10s
  timeout: 3s
  retries: 12
  start_period: 30s
```

Check health status:

```bash theme={null}
docker inspect ccs-dashboard --format='{{.State.Health.Status}}'
```

## Graceful Shutdown

CCS handles `SIGTERM` gracefully. When stopping the container:

```bash theme={null}
docker stop ccs-dashboard        # Sends SIGTERM, waits 10s, then SIGKILL
docker stop -t 30 ccs-dashboard  # Wait 30s for graceful shutdown
```

The `init: true` in `docker-compose.yml` ensures proper signal forwarding to the Node.js process.

## Using Pre-installed CLIs

The container includes pre-installed CLI tools for convenience.

### Execute Commands Inside Container

```bash theme={null}
# Open shell
docker exec -it ccs-dashboard bash

# Claude (non-interactive mode)
docker exec -it ccs-dashboard claude -p "Hello from Docker"

# Gemini
docker exec -it ccs-dashboard gemini "Hello from Docker"

# Grok
docker exec -it ccs-dashboard grok "Hello from Docker"

# OpenCode
docker exec -it ccs-dashboard opencode --help

# CCS
docker exec -it ccs-dashboard ccs --help
```

### Configure Credentials

Each CLI has its own authentication method. Refer to their respective documentation:

```bash theme={null}
docker exec -it ccs-dashboard claude --help
docker exec -it ccs-dashboard gemini --help
```

## Troubleshooting

### Permission Errors (EACCES)

If you see permission errors on startup:

```bash theme={null}
# Check volume permissions
docker exec ccs-dashboard ls -la /home/node/.ccs

# Fix by recreating volumes
docker-compose down -v
docker-compose up -d
```

### Port Already in Use

```bash theme={null}
# Check what's using the port
lsof -i :3000
lsof -i :8317

# Use different ports
docker run -p 4000:3000 -p 9317:8317 ...

# Or with compose
CCS_DASHBOARD_PORT=4000 CCS_CLIPROXY_PORT=9317 docker-compose up -d
```

### Container Keeps Restarting

```bash theme={null}
# Check logs for errors
docker logs ccs-dashboard --tail 50

# Check container health
docker inspect ccs-dashboard --format='{{.State.Health.Status}}'

# Check resource usage
docker stats ccs-dashboard
```

### Debug Mode

Enable verbose logging:

```bash theme={null}
docker run -e CCS_DEBUG=1 ...
```

Or update `docker-compose.yml`:

```yaml theme={null}
environment:
  CCS_DEBUG: "1"
```

### Image Build Fails

Common issues:

**Network timeout during build:**

```bash theme={null}
docker build --network=host -f docker/Dockerfile -t ccs-dashboard:latest .
```

**Out of disk space:**

```bash theme={null}
docker system prune -a
```

**Cache issues:**

```bash theme={null}
docker build --no-cache -f docker/Dockerfile -t ccs-dashboard:latest .
```

## Security Best Practices

### Secrets Management

For sensitive values like `CCS_PROXY_AUTH_TOKEN`:

**Option 1: .env file (not committed to git)**

```bash theme={null}
echo "CCS_PROXY_AUTH_TOKEN=your-secret-token" >> .env
docker-compose up -d
```

**Option 2: Docker secrets (Swarm mode)**

```bash theme={null}
echo "your-secret-token" | docker secret create ccs_proxy_token -
```

### Network Security

* **Bind to localhost only** - For development:
  ```bash theme={null}
  docker run -p 127.0.0.1:3000:3000 -p 127.0.0.1:8317:8317 ...
  ```

* **Use reverse proxy** - For production (nginx, traefik):
  ```nginx theme={null}
  server {
      listen 443 ssl http2;
      server_name ccs.example.com;

      location / {
          proxy_pass http://localhost:3000;
      }
  }
  ```

### Updates

Regularly rebuild the image to get security patches:

```bash theme={null}
docker-compose build --pull
docker-compose up -d
```

## Production Deployment

For production deployments, consider:

1. **Use Docker Compose** - Easier management and configuration
2. **Set resource limits** - Prevent resource exhaustion
3. **Enable healthcheck** - Auto-restart on failures
4. **Use .env file** - Separate config from code
5. **Backup volumes** - Regular backups of `ccs_home`
6. **Monitor logs** - Centralized logging (ELK, Loki)
7. **Reverse proxy** - nginx/traefik with TLS
8. **Secret management** - Docker secrets or vault

## Next Steps

<CardGroup cols={2}>
  <Card title="Remote Proxy Deployment" icon="server" href="/tutorials/remote-proxy-deployment">
    Deploy CLIProxyAPI on a remote server for centralized access
  </Card>

  <Card title="Multi-Account Setup" icon="users" href="/tutorials/multi-account-setup">
    Manage multiple OAuth accounts in Docker
  </Card>
</CardGroup>
