Skip to content

Port Allocation Registry

This document is the single source of truth for every host port consumed by Crow itself, by bundles in bundles/, and reserved by the MVP roadmap. Any new bundle PR that introduces a port binding must amend this file in the same PR. CI enforces that:

  1. Every host port in any bundles/**/docker-compose.yml is listed here.
  2. No two bundles map the same host port.

Conventions

  • All bundle ports bind to 127.0.0.1 unless the bundle is explicitly a reverse proxy (Caddy) or uses network_mode: host (browser, companion, coturn, plex, tailscale, crowdsec-firewall-bouncer).
  • "Existing" rows are bundles already shipped before this registry was introduced — they are recorded here so future bundles avoid them.
  • "Reserved" rows are claimed by upcoming Phase 2 bundles; do not consume them for unrelated work.
  • "MVP" rows are claimed by the bundles in the current MVP plan.
  • Not every row is a Docker port: bundles whose payload is supervised directly by the gateway (e.g. perch-hub, a vendored Node process) claim their loopback ports here too, so nothing else takes them. The perch-hub block deliberately sits clear of upstream Perch's own defaults (4200/4201, pool 4101-4139) so a crow-supervised hub and a standalone pi-hub can coexist on one host — do not "tidy" them onto those numbers.

Known conflicts in current bundles/

These predate this registry and need follow-up resolution outside the MVP scope:

PortConflict
8080LocalAI and Nextcloud both bind 127.0.0.1:8080 — they cannot run simultaneously

Allocation table

PortBindingBundle / ServiceStatus
22hosthost sshdreserved (system)
25mail SMTPreserved (Phase 2 mail)
53hosthost DNS / systemd-resolvedreserved (system)
800.0.0.0Caddy (reverse proxy + ACME HTTP-01)MVP PR 0.5
143mail IMAPreserved (Phase 2 mail)
4430.0.0.0CaddyMVP PR 0.5
465mail SMTPSreserved (Phase 2 mail)
587mail submissionreserved (Phase 2 mail)
993mail IMAPSreserved (Phase 2 mail)
2222(avoid: common host anti-scan sshd port)avoid
2019127.0.0.1Caddy admin API (host-local)MVP PR 0.5
2223127.0.0.1gitea (SSH)MVP PR 5
2224127.0.0.1forgejo (SSH)MVP PR 5
2283127.0.0.1immich (existing — verify in compose)existing
3001127.0.0.1Crow gateway (HTTPS)core
3002127.0.0.1Crow gateway (alt)core
3004127.0.0.1Crow gateway (alt)core
3007127.0.0.1uptime-kumaMVP PR 1
3008127.0.0.1Crow gateway (alt)core
3020127.0.0.1adguard-home (admin UI)MVP PR 3
3030127.0.0.1homepageMVP PR 1
3040127.0.0.1gitea (web)MVP PR 5
3050127.0.0.1forgejo (web)MVP PR 5
3061127.0.0.1rookery (OpenScience reviewer)PR #157
3080127.0.0.1romm (existing)existing
3456127.0.0.1vikunja (existing)existing
4141-4179127.0.0.1perch-hub — pi session pool (one port per live session, allocated by the hub; PI_HUB_POOL_START/PI_HUB_POOL_END)perch-hub P1
4210127.0.0.1perch-hub — hub web UI, reached only via the gateway proxy at /proxy/perch-hub (CROW_PERCH_PORT)perch-hub P1
4211127.0.0.1perch-hub — session registry (hub-internal, never proxied) (CROW_PERCH_REGISTRY_PORT)perch-hub P1
4533127.0.0.1navidrome (existing)existing
5000127.0.0.1kavita (existing)existing
5006127.0.0.1actual-budget (existing)existing
5010127.0.0.1changedetectionMVP PR 1
5042rotki (web/API)reserved (Phase 2 finance)
5080plausiblereserved (Phase 2 analytics)
5335127.0.0.1adguard-home (DNS, TCP+UDP)MVP PR 3
5336pi-hole (DNS)reserved (Phase 2 DNS)
5337technitium (DNS)reserved (Phase 2 DNS)
6080127.0.0.1browser (noVNC, existing) — overridable via CROW_BROWSER_VNC_PORT; RFB 5900 via CROW_BROWSER_RFB_PORT, CDP 9222 via CROW_BROWSER_CDP_PORT. Secondary instances on one host pick +1 offsets (6081/5901/9223), and MUST also set a distinct X display number via CROW_BROWSER_DISPLAY (default 99, secondary 98) — under network_mode: host two instances on the same display collideexisting
6875127.0.0.1bookstack (existing)existing
8000127.0.0.1paperless (existing)existing
8002tailscale IPed-jobs-scraper backend — freed 2026-07-26 (stack migrated to grackle :8002)external, freed
8004127.0.0.1faster-whisper-server (local STT)existing
8007127.0.0.1llamacpp-cpu-qwen3-embed (CPU embeddings)PR #111
8080127.0.0.1localai (existing) — also nextcloud, conflictexisting
8081127.0.0.1calibre-server (existing)existing
8083127.0.0.1calibre-web (existing)existing
8084127.0.0.1wallabag (existing)existing
8085127.0.0.1miniflux (existing)existing
8086127.0.0.1shiori (existing)existing
8088127.0.0.1trilium (existing)existing
8089127.0.0.1 + tailscale IPedjobs nominatim (external, ~/ed-jobs-scraper) — R4 GIS tools + grackle scraper stack (ufw-scoped)external
8090127.0.0.1capstone-trackershipped
8091127.0.0.1crowdsec (LAPI)MVP PR 4
8092127.0.0.1stirling-pdfMVP PR 1
8094127.0.0.1gatusMVP PR 2
8095127.0.0.1dozzleMVP PR 2
8096127.0.0.1jellyfin (existing)existing
8097127.0.0.1vaultwardenMVP PR 5
8098127.0.0.1searxngMVP PR 5
8010100.118.41.122 (tailscale)llamacpp-vulkan-qwen36-27b-copilot — co-resident critic refute/probe model, 65536 ctx, text-only (crow-addons)existing (2026-07-06)
8530127.0.0.1adguard-home (DNS-over-TLS)MVP PR 3
8554127.0.0.1frigate (RTSP restream)existing
8555127.0.0.1frigate (WebRTC)existing
8765127.0.0.1motioneyeexisting
8880127.0.0.1kokoro-tts (local TTS)existing
8971127.0.0.1frigate (authenticated UI)existing
9000127.0.0.1minio (S3 API, existing)existing
9001127.0.0.1minio (console, existing)existing
9090127.0.0.1linkding (existing)existing
11434127.0.0.1ollama (existing)existing
13378127.0.0.1audiobookshelf (existing)existing
18100-18199gateway-internal loopbacknative model servers (per-CROW_HOME dynamic range, not bundle ports — managed by servers/gateway/models/state.js)informational
18789127.0.0.1openclaw-old-docker (pre-existing external process)existing
19999127.0.0.1netdataMVP PR 2
32400hostplex (host networking, existing)existing

Host-networked bundles (no 127.0.0.1 binding — uses host stack directly)

These bundles use network_mode: host. They consume whatever ports their upstream service expects directly on the host:

  • browser (Chrome DevTools — verify ports)
  • companion (verify)
  • coturn (3478 UDP, plus turnserver listen ports)
  • plex (32400, plus discovery ports)
  • tailscale (MagicDNS, peer connections)
  • crowdsec-firewall-bouncer (deferred to PR 4.5 — upstream does not publish a Docker image; needs a custom Dockerfile and a tested unwind command verified on a throwaway host) — will need host network to manipulate iptables/nftables

Process for amending this file

  1. Pick an unallocated port in a sensible range (admin UIs in 3000-3099, backend APIs in 8000-8099, metrics in 19000-19999).
  2. Add a row to the table with bundle name and PR/status.
  3. CI port-collision check (the static-checks job in .github/workflows/test.yml) verifies your new port doesn't clash.
  4. Reference this file in your bundle's PR description.

Released under the MIT License.