port-forward

command module
v0.0.0-...-cab512a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2026 License: MIT Imports: 12 Imported by: 0

README

port-forward

A terminal app that keeps a set of Kubernetes port-forwards alive — one config file, one command, one live status view.

Port Forwards

  NAME           CONTEXT  TARGET                    LOCAL  STATUS      RESTARTS
▸ argocd         dev      argocd/argocd-server:443  :8080  running     0
  grafana        dev      monitoring/grafana:80     :3000  running     1
  grafana-stage  stage    monitoring/grafana:80     :3001  restarting  2

q quit   r restart selected   enter details   ↑/↓ select

Why

kubectl port-forward is fine for a quick one-off session, but it does not survive daily development:

  • It exits as soon as its connection to the pod is lost — a rollout, a pod restart, a dropped backend connection — and never reconnects on its own.
  • Forwarding several services means one terminal (or tmux pane) per service, each running its own kubectl port-forward.
  • There is no consolidated view of what is still alive; you find out a forward died when your request hangs.

port-forward starts every forward you configure, supervises each one independently, restarts it automatically when it dies, and renders a live status table instead of scrolling logs.

It drives kubectl under the hood, so kubeconfig handling, auth plugins, context selection, and service-to-pod resolution behave exactly like the tooling you already use.

Install

go install github.com/german-swan/port-forward@latest

Requirements:

  • kubectl 1.24+ on PATH (used as the port-forward backend).
  • Go 1.24+ (only to install or build).

Or build from source:

git clone https://github.com/german-swan/port-forward
cd port-forward
just build        # builds bin/port-forward

Configure

Create a port-forwards.yaml (start from port-forwards.example.yaml):

forwards:
  # Argo CD UI/API -> https://localhost:8080
  - name: argocd            # unique display name
    context: dev            # kubeconfig context; omit to use the current one
    namespace: argocd
    service: argocd-server  # forwarded as svc/<service>
    remotePort: 443
    localPort: 8080         # must be unique across all forwards

  # Grafana -> http://localhost:3000
  - name: grafana
    context: dev
    namespace: monitoring
    service: grafana
    remotePort: 80
    localPort: 3000

  # The same service from another cluster on another local port
  - name: grafana-stage
    context: stage
    namespace: monitoring
    service: grafana
    remotePort: 80
    localPort: 3001

Each entry runs the equivalent of:

kubectl --context dev --namespace monitoring port-forward svc/grafana 3000:80

The config is validated before anything starts: unknown YAML keys, missing fields, invalid ports, and duplicate names or local ports are all rejected up front.

Use

port-forward                      # uses ./port-forwards.yaml
port-forward -c ~/forwards.yaml   # or any other path
Key Action
/, k/j select a forward
enter details view (status, last error, recent logs)
esc back to the table
r restart the selected forward
q, Ctrl-C stop all forwards and quit

The app runs in the terminal's alternate screen and rewrites the view in place; raw kubectl output is never printed to the terminal. The last 200 log lines per forward are kept in memory and shown in the details view.

Behavior

  • Each forward runs kubectl [--context <ctx>] --namespace <ns> port-forward svc/<service> <local>:<remote> under its own supervisor.
  • A forward that exits unexpectedly is restarted after 1s. While a forward cannot be established at all, the delay doubles up to 30s and the status escalates from restarting to error after 3 consecutive failed attempts. It keeps retrying either way.
  • Ctrl-C, q, or SIGTERM stop everything: each kubectl process gets SIGTERM and 3 seconds to exit before being killed, then the terminal is restored. User-initiated shutdown exits with status 0.

Development

just test   # go test ./...
just vet    # go vet ./...
just fmt    # gofmt -w .

Package layout follows the supervisor/TUI split: internal/config (YAML loading and validation), internal/forward (kubectl subprocess supervision, status events), internal/tui (Bubble Tea model and views), internal/ring (recent-log buffer), and the root package (entrypoint wiring signals, the event channel, and the TUI together). See SPEC.md for the full requirements and design.

License

MIT

Documentation

Overview

Command port-forward keeps a configured set of kubectl port-forwards running and shows their status in a terminal UI.

Directories

Path Synopsis
internal
config
Package config loads and validates the port-forward YAML configuration.
Package config loads and validates the port-forward YAML configuration.
forward
Package forward supervises kubectl port-forward subprocesses, restarting them when they exit and reporting their state as events.
Package forward supervises kubectl port-forward subprocesses, restarting them when they exit and reporting their state as events.
ring
Package ring provides a fixed-capacity buffer that keeps the most recently appended items.
Package ring provides a fixed-capacity buffer that keeps the most recently appended items.
tui
Package tui implements the Bubble Tea terminal UI: a live table of all forwards plus a per-forward details view with recent logs.
Package tui implements the Bubble Tea terminal UI: a live table of all forwards plus a per-forward details view with recent logs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL