Network and ports for PanDev Metrics on-prem
PanDev Metrics on-prem runs two application ports on the host: 8080 for the backend API and 8090 for the workspace UI. In production, expose them through a reverse proxy on 443 instead of opening those ports directly to users. A third port, 9090, is the Spring Boot actuator and stays private. This page lists every inbound and outbound network requirement, the recommended reverse-proxy setup, and TLS options.
Security model — your data stays in your perimeter
PanDev Metrics on-prem runs entirely inside your infrastructure. The analytics database (PostgreSQL) and every component live in your perimeter — no telemetry, analytics, or source data is ever sent to the PanDev vendor or any third party.
- PanDev Metrics opens connections only to the systems you explicitly connect: your Git provider, your task tracker, and an optional LDAP/AD server.
- With self-managed providers (GitLab self-managed, Jira Data Center, Azure DevOps Server, GitHub Enterprise Server) traffic stays between the systems you operate.
- With a cloud provider (Azure DevOps Services, GitHub.com, Jira Cloud) PanDev Metrics exchanges data only with that same cloud — the one where your data already lives. No new external recipient is introduced.
- For Git, only metadata is stored (commits, pull requests, pipeline runs) — source code is never stored. See How the plugin works.
- The only connection to PanDev's own infrastructure is license validation — an HTTPS call to the PanDev license server that carries license and instance identifiers only, never your analytics, code, or metadata.
The rest of this page details the exact ports and connection directions behind these guarantees.
At a glance
| Property | Value |
|---|---|
| Data residency | All data stays inside your perimeter — nothing is sent to the PanDev vendor or third parties |
| Public inbound | TCP 443 to the reverse proxy only |
| Private/service inbound | TCP 9090 (actuator), 5432 (PostgreSQL) |
| Outbound | HTTPS to configured integrations and the PanDev license server — minimal, cannot be disabled |
| Integration webhooks | Inbound HTTPS from connected Git providers / task trackers to the backend's public URL (paths under /v1/…) |
| TLS | Terminated at the reverse proxy with a certificate trusted by browsers and IDE plugins |
| Air-gapped | Not supported |
Recommended production exposure
For Docker Compose on a VM, make Nginx the only public entry point:
| Public surface | Public URL | Local target on the VM |
|---|---|---|
| Workspace UI | https://app.example.com | http://127.0.0.1:8090 |
| Backend API, IDE plugins, webhooks | https://metrics.example.com | http://127.0.0.1:8080 |
| PostgreSQL | Do not expose | Docker bridge network / local host only |
| Actuator | Do not expose | Private container port 9090 or monitoring path only |
If the reverse proxy runs on a separate host or load balancer, route it to the VM's private IP and allow 8080 / 8090 only from that proxy. The browser-facing API_BASE_URL must be the public backend URL, not a Docker service hostname.
Inbound ports
Two host ports carry application traffic; keep them reachable only from the reverse proxy:
| Port | Service | Purpose | Exposure |
|---|---|---|---|
| 8080 | Backend (server) | REST API for the workspace and IDE plugins | Reverse-proxy target only |
| 8090 | Workspace (UI) | The web UI — a static React bundle served by Nginx | Reverse-proxy target only |
| 9090 | Spring Boot actuator | Health, metrics, info endpoints | Private service port — not published by the Compose file |
The database port is not part of the public surface:
| Port | Service | Exposure |
|---|---|---|
| 5432 | PostgreSQL | Published to the host by the bundled Compose file. The backend reaches the database over the Docker network — bind it to 127.0.0.1 or firewall it off |
Port 8080 — backend API
The backend serves the REST API used by the workspace and by IDE plugins. It must be reachable from:
- The reverse proxy (this is the local target behind the public
API_BASE_URL) - IDE plugin hosts that can reach the public backend URL
- Connected Git providers and task trackers, which POST webhooks to the backend (see Integration webhooks)
For production, make those clients reach the backend through https://metrics.example.com on 443; do not require them to connect to :8080 directly.
If the public backend URL is temporarily unreachable from developer workstations, IDE plugins do not lose data. The plugins buffer events locally and replay them once connectivity is restored.
Port 8090 — workspace UI
The workspace container (Nginx) serves the single-page UI. Browsers load the UI from this port, and the UI then calls the backend directly at API_BASE_URL — so both the UI host and the API host must be reachable from the user's browser. In production, publish the UI as https://app.example.com on 443 and proxy it to :8090. See Installation → about API_BASE_URL.
Port 9090 — actuator
The Spring Boot actuator exposes operational endpoints used for health checks and metrics scraping. In Docker Compose it is not published to the host; in the Helm chart it backs the pod liveness/readiness probes. Restrict it to your monitoring network — never expose it to the public internet.
Common actuator endpoints:
| Endpoint | Purpose |
|---|---|
/actuator/health/liveness | Liveness probe target |
/actuator/health/readiness | Readiness probe target |
/actuator/health | Aggregated health — returns {"status":"UP"} when healthy |
/actuator/info | Build and version information |
/actuator/metrics | Application metrics |
Outbound egress
PanDev Metrics on-prem requires minimal outbound HTTPS:
- The PanDev license server (the exact hostname is provided with your license) — for license activation on first launch and ongoing license validation. Required even before you connect any integration.
- Your Git provider (GitHub, GitLab Self-Managed or Cloud, Bitbucket, Azure DevOps)
- Your task tracker (Jira Cloud or Data Center, YouTrack, ClickUp, Yandex Tracker, Azure Boards)
- Optional LDAP / Active Directory server (if LDAP integration is enabled)
Outbound egress is minimal but cannot be disabled. Air-gapped deployments are not supported.
Open egress on TCP 443 to the PanDev license server and to the hostnames of the integrations you configure. If your network uses an HTTP proxy, set HTTPS_PROXY and NO_PROXY in the backend container environment.
Integration webhooks (inbound)
Integrations are bidirectional — the outbound HTTPS above is only half of it. Each connected Git provider and task tracker must also be able to reach PanDev Metrics to deliver webhooks. This is what drives real-time sync; without inbound reachability, data updates only on the periodic backfill, not on each event.
Connection direction by integration
| Integration | Ports | Direction | Why |
|---|---|---|---|
| Git provider (GitHub, GitLab, Bitbucket, Azure DevOps) | 443 | Bidirectional | Egress: API poll and backfill. Inbound: webhooks for pushes, pull / merge requests, and pipeline runs |
| Task tracker (Jira, YouTrack, ClickUp, Yandex Tracker, Azure Boards) | 443 | Bidirectional | Egress: API poll and backfill. Inbound: webhooks for issues, state changes, and worklog |
| AD / LDAP / LDAPS | 389, 636 | Unidirectional — PanDev → LDAP | User and group sync plus authentication. The directory never opens a connection back to PanDev Metrics |
Webhooks are HTTP POSTs sent from the provider to the backend's public URL, on paths under /v1/… — for example /v1/github/webhook/pull-request, /v1/gitlab/webhook/merge-request, or /v1/jira-worklog. They arrive on the same public endpoint as the API: normally 443 on the reverse proxy, forwarded internally to backend port 8080.
What this means for the network:
- Cloud providers (GitHub.com, GitLab SaaS, Bitbucket Cloud, Jira Cloud, Azure DevOps Services) deliver webhooks from the internet — the PanDev Metrics webhook URL must be reachable from the public internet (typically your reverse proxy on
443). - Self-managed providers (GitHub Enterprise Server, GitLab self-managed, Bitbucket Data Center, Jira Data Center) must reach the same backend URL through your routing.
:::note Azure DevOps is always bidirectional Azure DevOps — both Services (cloud) and Server (self-managed) — needs reachability in both directions:
- PanDev → Azure (outbound 443): PanDev Metrics registers the service hooks, polls the REST API, runs the backfill, and posts PR comments.
- Azure → PanDev (inbound to the backend webhook URL): Azure creates the service hooks itself and POSTs events — pull requests, pipeline runs, and Azure Boards work items — to PanDev Metrics.
Without inbound Azure → PanDev reachability there is no real-time sync: data only arrives through the 15-minute reconciliation backfill. See the Azure DevOps and Azure Boards guides. :::
In short, INTEGRATION ↔ METRICS visibility must be mutual: egress so the backend can call and back-fill from the provider, and inbound so the provider can deliver webhooks. The public URL providers call is configured in PanDev Metrics — see the per-integration guides under Git integrations and task trackers.
Reverse proxy
Terminate TLS at a reverse proxy and route two names: the UI to the workspace (:8090) and the API to the backend (:8080). Nginx and Traefik are both fine — the shape is a standard HTTP reverse proxy. Configure this before the first production start of the workspace, or recreate the workspace container after changing API_BASE_URL.
Nginx
# Workspace UI
server {
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/ssl/certs/pandev.crt;
ssl_certificate_key /etc/ssl/private/pandev.key;
location / {
proxy_pass http://127.0.0.1:8090;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Backend API (this hostname is your API_BASE_URL)
server {
listen 443 ssl http2;
server_name metrics.example.com;
ssl_certificate /etc/ssl/certs/pandev.crt;
ssl_certificate_key /etc/ssl/private/pandev.key;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
}
}
Traefik
http:
routers:
pandev-ui:
rule: "Host(`app.example.com`)"
entryPoints: [websecure]
tls: {}
service: pandev-workspace
pandev-api:
rule: "Host(`metrics.example.com`)"
entryPoints: [websecure]
tls: {}
service: pandev-backend
services:
pandev-workspace:
loadBalancer:
servers:
- url: "http://127.0.0.1:8090"
pandev-backend:
loadBalancer:
servers:
- url: "http://127.0.0.1:8080"
On Kubernetes, the bundled Helm chart creates this routing for you from serverUrl and workspaceUrl via an Ingress — see Installation → Helm.
TLS and reverse proxy options
PanDev Metrics expects TLS at the reverse proxy. Choose the certificate model that matches your security policy.
| Option | What you set up | When to use |
|---|---|---|
| Public CA certificate | Reverse proxy with a certificate from Let's Encrypt or your enterprise CA | Default — recommended for any production install reachable from developer workstations |
| Enterprise CA certificate | Reverse proxy with a certificate from a CA your fleet already trusts | Environments where browsers and IDE plugin hosts trust that CA |
Use a certificate chain trusted by the browsers and IDE plugin hosts that connect to PanDev Metrics.
Firewall rules
Minimum recommended inbound rule on the application host:
firewall-cmd --permanent --add-port=443/tcp # reverse proxy only
firewall-cmd --reload
If you run an external database on a separate host, restrict PostgreSQL to accept connections only from the application host IP:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" \
source address="<APPLICATION_HOST_IP>" port port="5432" protocol="tcp" accept'
firewall-cmd --reload
The bundled Docker Compose file publishes PostgreSQL on 5432 to the host. The backend reaches the database over the Docker network, so bind the port to 127.0.0.1 (or block it at the firewall) rather than leaving it on all interfaces.
HTTP proxy environment
If the application host sits behind a corporate HTTP proxy, configure it through standard environment variables on the backend service:
| Variable | Purpose |
|---|---|
HTTP_PROXY | Proxy URL for plain HTTP — rarely used |
HTTPS_PROXY | Proxy URL for outbound HTTPS to Git / task tracker |
NO_PROXY | Comma-separated hosts to bypass the proxy (PostgreSQL and other service dependencies) |
Add these to the pandev-metrics-server service environment, then docker compose up -d --force-recreate pandev-metrics-server.
Constraints and edge cases
- Egress cannot be disabled. PanDev Metrics needs minimal outbound HTTPS to validate its license against the PanDev license server and to talk to integrations. There is no offline mode.
- Actuator must stay private. Port 9090 is not designed to be a public surface.
- No mTLS between components. The backend and PostgreSQL communicate over the Docker/Kubernetes service network. Add mTLS at the network layer if your policy requires it.
- WebSocket support depends on the reverse proxy. Long-running connections used by parts of the UI need
proxy_read_timeoutraised above the default 60 seconds on Nginx.
Related
- How-to: Install PanDev Metrics on-prem
- Reference: System requirements
- Concept: On-prem architecture