Skip to main content
Version: v2 (current)

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

PropertyValue
Data residencyAll data stays inside your perimeter — nothing is sent to the PanDev vendor or third parties
Public inboundTCP 8080 (backend API) and 8090 (workspace UI) — or 443 behind a reverse proxy
Internal inboundTCP 9090 (actuator), 5432 (PostgreSQL)
OutboundHTTPS to configured integrations and the PanDev license server — minimal, cannot be disabled
Integration webhooksInbound HTTPS from connected Git providers / task trackers to the backend's public URL (paths under /v1/…)
TLSTerminated at reverse proxy or via self-signed certificate with client-side validation disabled
Air-gappedNot supported

Inbound ports

Two ports carry user traffic; the actuator stays internal:

PortServicePurposeExposure
8080Backend (server)REST API for the workspace and IDE pluginsPublic (typically behind a reverse proxy on 443)
8090Workspace (UI)The web UI — a static React bundle served by NginxPublic (typically behind a reverse proxy on 443)
9090Spring Boot actuatorHealth, metrics, info endpointsInternal only — not published by the Compose file

The database port is not part of the public surface:

PortServiceExposure
5432PostgreSQLPublished 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:

EndpointPurpose
/actuator/health/livenessLiveness probe target
/actuator/health/readinessReadiness probe target
/actuator/healthAggregated health — returns {"status":"UP"} when healthy
/actuator/infoBuild and version information
/actuator/metricsApplication 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)
warning

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

IntegrationPortsDirectionWhy
Git provider (GitHub, GitLab, Bitbucket, Azure DevOps)443 (or 80)BidirectionalEgress: 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)BidirectionalEgress: API poll and backfill. Inbound: webhooks for issues, state changes, and worklog
AD / LDAP / LDAPS389, 636Unidirectional — PanDev → LDAPUser 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

/etc/nginx/conf.d/pandev.conf
# 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

traefik dynamic config
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.

OptionWhat you set upWhen to use
Public CA certificateReverse proxy with a certificate from Let's Encrypt or your enterprise CADefault — recommended for any production install reachable from developer workstations
Internal CA certificateReverse proxy with an internal CA your fleet already trustsCorporate networks where developer machines trust an internal CA
Self-signed + client validation disabledBackend served directly with a self-signed certificate, plugins configured to skip SSL validationAir-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:

terminal (firewalld example)
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:

terminal (firewalld example — external DB host)
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:

VariablePurpose
HTTP_PROXYProxy URL for plain HTTP — rarely used
HTTPS_PROXYProxy URL for outbound HTTPS to Git / task tracker
NO_PROXYComma-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_timeout raised above the default 60 seconds on Nginx.

Citations