# HODA — the main host: serves the dashboard of every labeled app on this host's Docker. # # Usage: # cp .env.example .env # the defaults fit the main host # docker compose pull # grab the latest image from the Gitea registry # docker compose up -d # # Point the Pangolin resource for apps.mariosem.es at http://HODA_BIND_IP:HODA_PORT # (http://10.20.30.10:10040 with .env.example) and turn SSO on: HODA has no login of its own. # # One host needs nothing else. A second Docker host runs docker-compose.agent.yml, and this # host then gets HODA_AGENT_URL and HODA_PEER_TOKEN in .env to pull that host's apps. # # The image is built and published by .gitea/workflows/ci.yml. name: hoda x-logging: &logging driver: json-file options: max-size: "10m" max-file: "3" services: hoda: image: git.mariosem.es/msemes/hoda:${HODA_TAG:-latest} container_name: hoda restart: unless-stopped # `:latest` is mutable; `always` makes `docker compose up -d` check the registry for a newer # image. If you pin HODA_TAG to a fixed tag, `missing` is enough. pull_policy: always depends_on: - socket-proxy environment: MODE: primary DOCKER_HOST: tcp://socket-proxy:2375 NODE_NAME: ${HODA_NODE_NAME:-host-1} DASHBOARD_TITLE: ${HODA_TITLE:-apps.mariosem.es} # Only with a second host: its agent's URL and the token both hosts share. HODA refuses to # start with an agent URL but no token. PEERS: ${HODA_AGENT_URL:-} PEER_TOKEN: ${HODA_PEER_TOKEN:-} LOG_LEVEL: ${HODA_LOG_LEVEL:-info} ports: # Published on one address only: loopback by default, or the LAN IP Pangolin reaches. - "${HODA_BIND_IP:-127.0.0.1}:${HODA_PORT:-8090}:8080" volumes: # Icon cache. Set HODA_DATA_DIR to bind-mount a host directory instead of the named volume; # it must be owned by the image's user first: sudo chown -R 65532:65532 /path/to/dir - ${HODA_DATA_DIR:-hoda_data}:/data # The binary only writes to /data, and needs no privileges. read_only: true cap_drop: [ALL] security_opt: ["no-new-privileges:true"] mem_limit: 128m cpus: 0.5 logging: *logging # Read-only Docker API for HODA: container lists and events, nothing else. No published port. socket-proxy: image: tecnativa/docker-socket-proxy:latest container_name: hoda-socket-proxy restart: unless-stopped environment: CONTAINERS: 1 EVENTS: 1 POST: 0 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro mem_limit: 64m logging: *logging volumes: # Fallback when HODA_DATA_DIR is unset; a no-op if /data is bind-mounted to a host path. hoda_data: