Komodo

Komodo is a container management and orchestration tool for deploying, monitoring, and managing Docker containers across multiple hosts.

This compose file deploys Komodo v2 with four services: the Komodo core service to provide a management console, a FerretDB instance, and a Komodo periphery agent which interacts with the docker socket to allow container monitoring and control.

Volumes are mounted using NFS, and the core UI is proxied through a Traefik reverse proxy with Cloudflare TLS certificates.

For more information, check out the official documentation.

Docker Compose

# compose.yaml

services:
  core:
    image: ghcr.io/moghtech/komodo-core:2
    container_name: komodo-core
    restart: unless-stopped
    depends_on:
      ferretdb:
        condition: service_healthy
    init: true
    # ports:
    #  - 9120:9120
    networks:
      - komodo
      - komodo_proxy
    volumes:
      - type: volume
        source: docker-nfs
        target: /backups
        volume:
          subpath: komodo/backups
      - type: volume
        source: docker-nfs
        target: /config/keys
        volume:
          subpath: komodo/keys/${VM_NAME}
    env_file: .env
    environment:
      KOMODO_DATABASE_ADDRESS: ferretdb:27017
      KOMODO_DATABASE_USERNAME: ${KOMODO_DB_USERNAME}
      KOMODO_DATABASE_PASSWORD: ${KOMODO_DB_PASSWORD}
      TZ: Europe/London
    labels:
      - "komodo.skip=true" # prevent Komodo from stopping with StopAllContainers

      - "traefik.enable=true"
      - "traefik.docker.network=komodo_proxy"

      - "traefik.http.services.komodo.loadbalancer.server.port=9120"

      - "traefik.http.routers.komodo.rule=Host(`komodo.${TRAEFIK_BASE_URL}`)"
      - "traefik.http.routers.komodo.entrypoints=websecure"
      - "traefik.http.routers.komodo.tls=true"
      - "traefik.http.routers.komodo.tls.certresolver=cloudflare"

  ferretdb:
    image: ghcr.io/ferretdb/ferretdb:2
    container_name: komodo-ferret
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    # ports:
    #   - 27017:27017
    networks:
      - komodo
    volumes:
      - type: volume
        source: docker-nfs
        target: /state
        volume:
          subpath: komodo/ferret
    healthcheck:
      test: ["CMD", "/ferretdb", "ping"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    environment:
      FERRETDB_POSTGRESQL_URL: postgres://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}@postgres:5432/${KOMODO_DB_NAME}
      TZ: Europe/London
    labels:
      komodo.skip:

  postgres:
    image: ghcr.io/ferretdb/postgres-documentdb:17
    container_name: komodo-postgres
    restart: unless-stopped
    # ports:
    #   - 5432:5432
    networks:
      - komodo
    volumes:
      - type: volume
        source: docker-nfs
        target: /var/lib/postgresql/data
        volume:
          subpath: komodo/postgres
    healthcheck:
      test:
        ["CMD", "pg_isready", "-U", "${KOMODO_DB_USERNAME}", "-d", "${KOMODO_DB_NAME}"]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      POSTGRES_USER: ${KOMODO_DB_USERNAME}
      POSTGRES_PASSWORD: ${KOMODO_DB_PASSWORD}
      POSTGRES_DB: ${KOMODO_DB_NAME}
      TZ: Europe/London
    labels:
      komodo.skip:

  periphery:
    image: ghcr.io/moghtech/komodo-periphery:2
    container_name: komodo-periphery
    restart: unless-stopped
    init: true
    networks:
      - komodo
    env_file: .env
    volumes:
      - type: volume
        source: docker-nfs
        target: /config/keys
        volume:
          subpath: komodo/keys/${VM_NAME}
      - /var/run/docker.sock:/var/run/docker.sock
      - /proc:/proc
      - ${PERIPHERY_ROOT_DIRECTORY}:${PERIPHERY_ROOT_DIRECTORY}
    environment:
      TZ: Europe/London
    labels:
      komodo.skip:

volumes:
  docker-nfs:
    driver: local
    driver_opts:
      type: nfs
      o: addr=xxx.xxx.xxx.xxx,nolock,soft,rw,nfsvers=4.2
      device: ":/mnt/nfs-volume"

networks:
  komodo:
    name: komodo
  komodo_proxy:
    name: komodo_proxy

Environment Variables

# .env

#=-------------=#
#= Komodo Core =#
#=-------------=#

VM_NAME=
TRAEFIK_BASE_URL=example.com
KOMODO_SESSION_ALLOW_CROSS_SITE=true
KOMODO_CORS_ALLOW_CREDENTIALS=true
KOMODO_CORS_ALLOWED_ORIGINS=https://komodo.${TRAEFIK_BASE_URL}

KOMODO_DB_USERNAME=
KOMODO_DB_PASSWORD=
KOMODO_DB_NAME=

KOMODO_HOST=https://komodo.${TRAEFIK_BASE_URL}
KOMODO_TITLE=Komodo
KOMODO_FIRST_SERVER=https://periphery:8120
KOMODO_DISABLE_CONFIRM_DIALOG=false

KOMODO_MONITORING_INTERVAL="15-sec"
KOMODO_RESOURCE_POLL_INTERVAL="1-hr"

KOMODO_WEBHOOK_SECRET= # random string
KOMODO_JWT_SECRET= # random string
KOMODO_JWT_TTL="1-day"

KOMODO_LOCAL_AUTH=true
KOMODO_DISABLE_USER_REGISTRATION=true
KOMODO_ENABLE_NEW_USERS=false
KOMODO_DISABLE_NON_ADMIN_CREATE=false
KOMODO_TRANSPARENT_MODE=false

KOMODO_LOGGING_PRETTY=false
KOMODO_PRETTY_STARTUP_CONFIG=false

KOMODO_OIDC_ENABLED=false

KOMODO_GITHUB_OAUTH_ENABLED=false

KOMODO_GOOGLE_OAUTH_ENABLED=false

KOMODO_AWS_ACCESS_KEY_ID=
KOMODO_AWS_SECRET_ACCESS_KEY=

#=------------------=#
#= Komodo Periphery =#
#=------------------=#

PERIPHERY_ROOT_DIRECTORY=

PERIPHERY_DISABLE_TERMINALS=false

PERIPHERY_SSL_ENABLED=true

PERIPHERY_INCLUDE_DISK_MOUNTS=/etc/hostname

PERIPHERY_LOGGING_PRETTY=false
PERIPHERY_PRETTY_STARTUP_CONFIG=false

Traefik

Modify your Traefik compose.yaml to enable access to the komodo_proxy network.

# compose.yaml (excerpt)

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    ...
    networks:
      - traefik
      # here
      - komodo_proxy
    ...

networks:
  # here
  komodo_proxy:
    name: komodo_proxy