Skip to content

Docker Layout

All services run as Docker containers, composed via docker-compose.yml files scattered across /opt/. There is no orchestrator above Docker Compose. This is deliberate — one machine, simple tools.

Container count

Total: 38 containers running. Captured 2026-08-12.

Containers grouped by function

Infrastructure base — shared by everything

Container Purpose Compose location
infra-nginx Reverse proxy, TLS termination /opt/infrastructure/nginx/
infra-certbot Let's Encrypt cert renewal same as nginx
infra-postgres Shared Postgres for most apps /opt/infrastructure/postgres/
infra-redis Shared Redis cache/queue /opt/infrastructure/redis/
infra-telegram-webhook Outbound Telegram bot relay /opt/infrastructure/telegram/
falco Runtime security monitoring /opt/infrastructure/falco/
clamav Malware scanner (antivirus) /opt/infrastructure/clamav/

Identity, secrets, code

Container Purpose Port
forgejo Git server (sovereign GitHub replacement) 3000 (http), 2222 (ssh)
vaultwarden Password vault internal
headscale Self-hosted Tailscale coordination server 3478, 8091

Application platforms

Container Purpose Port
admin-dashboard Control Center SPA at joaoluisbrazao.cloud 8084
dashboard-refresh Periodic dashboard data refresher
rabbithall Admin/ops UI for VPS internals 5001

LLM and skills

Container Purpose Port
litellm LLM proxy router (25 models, cost cap) 4000
jb-skills-gateway Paperclip skills runtime, 43 skills 8095

Gamine (maternal care platform)

Container Purpose Port
gamine-web Hub + agency + backoffice frontend 8090
gamine-app Backend app
gamine-db Postgres for Gamine 5432 (internal)
gamine-minio Object storage for Gamine 9000 (internal)
gamine-brain-api Gamine intelligence API 8140
gamine-brain-web Gamine intelligence frontend 8141

JB Brain (knowledge graph)

Container Purpose Port
jb-brain-api Brain API + RAG 8130
jb2b-api Curator backend, Q&A claims routing 8120
ghrepos-api Skills catalog (open-source agents) 8086

Gestso (Odoo ERP)

Container Purpose Port
sandbox-odoo-web Odoo 18 web 8210
sandbox-odoo-db Odoo Postgres 5432 (internal)
sandbox-odoo-docai Document AI extractor 8211

Productivity / ops

Container Purpose Port
vikunja Task manager (single source of truth) 3456
uptime-kuma Uptime monitoring, 36 monitors 3001
triage-bot Email triage automation
triage-dashboard Triage UI 8082
bear-overnight Overnight batch worker

Conventions

  • Every container has a healthcheck where the runtime allows it
  • Every volume is named — never anonymous -v mounts
  • No latest tag in any production image — pinned versions only
  • Containers expose ports to 127.0.0.1 by default. Nginx is the only public entry point on 0.0.0.0
  • Resource limits should be set per container (some are missing — see tech-debt.md)

Where compose files live

/opt/infrastructure/{nginx,postgres,redis,...}/docker-compose.yml
/opt/prod/gamine/docker-compose.yml
/opt/prod/jb-brain/docker-compose.yml
/opt/rabbithall-compose/docker-compose.yml
/opt/ghrepos-api/docker-compose.yml

If unsure where a container's compose is: docker inspect <name> | grep com.docker.compose.project.config_files.