Network and ports for PanDev Metrics on-prem
import Head from "@docusaurus/Head";
PanDev Metrics on-prem publishes two TCP ports for users: 8080 for the backend API and 8090 for the workspace UI. A third port, 9090, is the Spring Boot actuator and stays internal. 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 never leaves your corporate network.
- 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 8080 (backend API) and 8090 (workspace UI) — or 443 behind a reverse proxy |
| Internal 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 reverse proxy or via self-signed certificate with client-side validation disabled |
| Air-gapped | Not supported |
Inbound ports
Two ports carry user traffic; the actuator stays internal:
| Port | Service | Purpose | Exposure |
|---|---|---|---|
| 8080 | Backend (server) | REST API for the workspace and IDE plugins | Public (typically behind a reverse proxy on 443) |
| 8090 | Workspace (UI) | The web UI — a static React bundle served by Nginx | Public (typically behind a reverse proxy on 443) |
| 9090 | Spring Boot actuator | Health, metrics, info endpoints | Internal only — 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 internal network — bind it to 127.0.0.1 or firewall it off for non-local installs |
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 address you publish as
API_BASE_URL) - IDE plugin hosts (developer workstations or VPN-connected machines)
- Connected Git providers and task trackers, which POST webhooks to the backend (see Integration webhooks)
If port 8080 is closed to developer workstations, IDE plugins do not lose data. The plugins buffer events locally and replay them once connectivity is restored over VPN or the corporate network.
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. 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 (or 80) | 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 (or 8080 / 80) | 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 (port 8080, normally fronted by your reverse proxy on 443).
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) only need to reach PanDev Metrics over your internal network.
:::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 public or internal 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.
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 works in any of the three TLS configurations below. Choose the one 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 |
| Internal CA certificate | Reverse proxy with an internal CA your fleet already trusts | Corporate networks where developer machines trust an internal CA |
| Self-signed + client validation disabled | Backend served directly with a self-signed certificate, plugins configured to skip SSL validation | Air-gapped testing or evaluation only — not recommended for production |
PanDev Metrics IDE plugins support disabling client-side SSL validation when connecting to a self-signed deployment. The setting is per-plugin and is documented in the plugin guides.
Firewall rules
Minimum inbound rules on the application host:
firewall-cmd --permanent --add-port=443/tcp # reverse proxy
firewall-cmd --permanent --add-port=8080/tcp # only if exposing the API without a proxy
firewall-cmd --permanent --add-port=8090/tcp # only if exposing the UI without a proxy
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 internal network, so for non-local installs 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 internal services) |
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 internal. Port 9090 is not designed to be a public surface.
- No mTLS between components. The backend and PostgreSQL communicate inside the trusted Docker/Kubernetes 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