# Komodo Deployment — Reference

**Installed:** 2026-07-09 on Core (netcup RS 2000)
**Version:** Komodo v2.2.0
**Purpose:** Multi-host Docker management across ITPP servers (Core, ai, docker, unms, etc.)
**Architecture:** Core (web UI + API server, port 9120) + MongoDB → Periphery agents on each managed host

## Directory Structure

```
/root/docker/komodo/
├── docker-compose.yml      # Core + MongoDB
├── data/
│   ├── mongo-data/         # MongoDB persistent storage
│   └── mongo-config/       # MongoDB config
├── backups/                # Database backups
└── keys/
    ├── core.key            # Core private key (auto-generated)
    └── core.pub            # Core public key (auto-generated)
```

## Docker Compose (Core)

```yaml
services:
  mongo:
    image: mongo
    restart: unless-stopped
    command: --quiet --wiredTigerCacheSizeGB 0.25
    volumes:
      - ./data/mongo-data:/data/db
      - ./data/mongo-config:/data/configdb
    networks:
      - komodo-net
    deploy:
      resources:
        limits:
          memory: 1G

  core:
    image: ghcr.io/moghtech/komodo-core:2
    init: true
    restart: unless-stopped
    ports:
      - 9120:9120
    depends_on:
      - mongo
    volumes:
      - ./backups:/backups
      - ./keys:/config/keys
    environment:
      # Database
      - KOMODO_DATABASE_ADDRESS=mongo:27017
      # Server
      - KOMODO_PORT=9120
      - KOMODO_HOST=https://komodo.itpropartner.com
      - KOMODO_TITLE=Komodo
      # Auth
      - KOMODO_LOCAL_AUTH=true
      - KOMODO_INIT_ADMIN_USERNAME=admin
      - KOMODO_INIT_ADMIN_PASSWORD=changeme
      # First server (this host)
      - KOMODO_FIRST_SERVER_NAME=core
      # Periphery auth
      - KOMODO_PERIPHERY_PUBLIC_KEY=file:/config/keys/periphery.pub
      # Secrets
      - KOMODO_WEBHOOK_SECRET=komodo-webhook-secret
      - KOMODO_JWT_SECRET=komodo-jwt-secret-change-me
      - KOMODO_JWT_TTL=1-day
      # Monitoring
      - KOMODO_MONITORING_INTERVAL=15-sec
      - KOMODO_RESOURCE_POLL_INTERVAL=1-hr
      # UI
      - KOMODO_DISABLE_CONFIRM_DIALOG=false
      - KOMODO_TRANSPARENT_MODE=false
    networks:
      - komodo-net
    deploy:
      resources:
        limits:
          memory: 512M

networks:
  komodo-net:
    driver: bridge
```

## Critical Env Variable Pitfalls (V2)

- **Do NOT use `MONGO_CONNECTION_STRING`** — Komodo v2 uses `KOMODO_DATABASE_ADDRESS=mongo:27017`
- **Do NOT use `KOMODO_SERVER_PORT`** — use `KOMODO_PORT=9120`
- **Do NOT use `KOMODO_SERVER_HOST`** — use `KOMODO_BIND_IP=[::]` (default)
- **`KOMODO_PERIPHERY_PUBLIC_KEY`** must be set with `file:/config/keys/periphery.pub` for auto-generation
- **`init: true`** is essential on the core container (handles PID 1 zombie reaping properly)
- **`KOMODO_HOST` must be set** to the URL users will access (used for OAuth redirects, webhook suggestions)

## Startup Log Verification

Successful startup shows:
```
Server starting on http://[::]:9120
Creating init admin user...
Successfully created init admin user.
Creating initial system resources...
```

The admin user is created on first launch only. Core v2.2.0 auto-creates starting resources: "Backup Core Database" procedure and "Global Auto Update" procedure.

## Admin Login (API)

```bash
# Get JWT token
curl -s -X POST http://127.0.0.1:9120/auth/login \
  -H "Content-Type: application/json" \
  -d '{"type":"Local","username":"admin","password":"changeme"}'
```

Note: the login body requires `"type":"Local"` — missing this field returns: _"Failed to deserialize the JSON body into the target type: missing field `type`"_

## Onboarding Key

The onboarding key is available in the Komodo web UI after login:
1. Go to the **Servers** page
2. Click **Add Server / Onboard**
3. Copy the onboarding key (starts with `O-`)

Or retrieve via the API with a valid JWT:
```bash
curl -s http://127.0.0.1:9120/api/core -H "Authorization: Bearer <token>"
# Extract onboarding_key from response
```

## Periphery Installation (on each managed host)

```bash
# Via systemd script (recommended for production)
curl -sSL https://raw.githubusercontent.com/moghtech/komodo/main/scripts/setup-periphery.py \
  | python3 - \
  --core-address="https://komodo.itpropartner.com" \
  --connect-as="$(hostname)" \
  --onboarding-key="O-..."
```

The Periphery agent communicates with Core via WebSocket. It listens on port 8120 by default. The agent runs as a systemd service when installed via the Python script.

## Docker Periphery (alternative, for containers)

```yaml
services:
  periphery:
    image: ghcr.io/moghtech/komodo-periphery:2
    init: true
    restart: unless-stopped
    depends_on:
      - core
    env_file: ./compose.env
    volumes:
      - keys:/config/keys
      - /var/run/docker.sock:/var/run/docker.sock
      - /proc:/proc
      - ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}:${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}
```

## Public Key Authentication

Core uses Noise protocol key pairs for Periphery authentication.

- Core keys auto-generated at: `/config/keys/core.key` and `/config/keys/core.pub`
- Periphery public key expected at: `/config/keys/periphery.pub` (auto-generated if `KOMODO_PERIPHERY_PUBLIC_KEY` is set and file doesn't exist)
- Example public key: `-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VuAyEAo+xXlRx+KcxbFkscAx3JcmGKudDwoID3AkGnzjFb1AE=\n-----END PUBLIC KEY-----`
