# How Starship Handles Port Forwarding for Local Access to Blockchain Nodes

> Starship simplifies local blockchain node access with automated Kubernetes port forwarding via a single CLI command. Effortlessly map service ports to localhost and manage your nodes.

- Repository: [Hyperweb/starship](https://github.com/hyperweb-io/starship)
- Tags: how-to-guide
- Published: 2026-03-03

---

**Starship automates Kubernetes port forwarding through a single CLI command that validates cluster readiness, maps logical service ports to localhost endpoints, and manages concurrent kubectl processes until manual termination.**

Starship, developed by hyperweb-io, eliminates the manual complexity of exposing blockchain nodes running in Kubernetes to your local development environment. The `connect` command streamlines **port forwarding for local access to blockchain nodes** by orchestrating multiple kubectl port-forward processes based on declarative configuration, enabling seamless interaction with chain RPC endpoints, REST APIs, and explorer interfaces.

## The Connect Command Architecture

The `connect` sub-command in [`starship/cmd/starship/connect.go`](https://github.com/hyperweb-io/starship/blob/main/starship/cmd/starship/connect.go) implements a six-stage workflow that transforms high-level service definitions into active localhost tunnels.

### Environment Validation and Prerequisites

Before establishing any tunnels, Starship validates the operational environment. The `client.CheckKubectl()` function verifies that the `kubectl` binary exists in `$PATH` and is executable. Subsequently, `client.CheckPortForward()` inspects the Kubernetes cluster to confirm that all required pods—including chain nodes, relayers, and explorers—are in the `Running` phase. This prevents connection attempts against containers that are still initializing or in a crash loop.

### Configuration-Driven Port Discovery

Starship reads the deployment configuration from a `Config` struct (defined in [`starship/tests/e2e/config.go`](https://github.com/hyperweb-io/starship/blob/main/starship/tests/e2e/config.go)) that contains a `Port` map for each infrastructure component. When you execute the connect command, the system iterates over every defined chain, relayer, and optional service to identify which endpoints require exposure. The configuration specifies logical service names that map to container ports without requiring developers to memorize pod names or internal cluster DNS entries.

### Default Port Mappings for Blockchain Components

The `defaultPorts` map in [`connect.go`](https://github.com/hyperweb-io/starship/blob/main/connect.go) establishes well-known port assignments for common blockchain interfaces. **Standard mappings include** `chain.rest` at **1317**, `chain.rpc` at **26657**, and `exposer` at **8081**. When a chain configuration specifies `cometmock` as the RPC provider, Starship automatically overrides the remote port to `defaultCometmockPort = 22331`, ensuring compatibility with the mock consensus engine.

## Building and Executing Kubectl Port Forwards

Once Starship validates the environment and parses the configuration, it constructs and executes the underlying kubectl commands that bridge the cluster-network boundary.

### Command Construction Logic

The `PortForwardCmds()` function generates port-forward specifications for every enabled service. For each endpoint, it calls `execPortForwardCmd(resource, localPort, remotePort)`, which returns an `*exec.Cmd` configured to run:

```bash
kubectl port-forward <resource> <localPort>:<remotePort> -n <namespace>

```

The `<resource>` parameter accepts either pod identifiers (e.g., `pods/cosmoshub-genesis-0`) or service names (e.g., `svc/explorer`). If the configuration specifies a custom namespace, the command builder appends the `-n` flag automatically. This abstraction allows developers to target specific chain validators or load-balanced services without manual kubectl syntax.

### Concurrent Execution and Error Handling

The `RunPortForward()` method launches each kubectl command in its own goroutine, enabling parallel initialization of multiple endpoints. A result channel aggregates success and failure states from each forwarder. If any individual port forward fails—due to port conflicts, permission errors, or pod termination—the context cancellation propagates to all running processes, ensuring clean shutdown rather than leaving orphaned kubectl instances.

The CLI blocks the main thread until the user sends an interrupt signal (Ctrl-C). Upon receiving the termination request, Starship cancels the parent context, which triggers graceful shutdown of all background kubectl processes and releases the bound localhost ports.

## Configuration Example: Defining Exposed Services

The `ports` stanza in your [`config.yaml`](https://github.com/hyperweb-io/starship/blob/main/config.yaml) declaratively specifies which services Starship should expose. Each component supports distinct port mappings that correspond to standard blockchain tooling interfaces:

```yaml
chains:
  - id: cosmoshub
    name: cosmoshub
    ports:
      rest: 1317      # Cosmos SDK REST server

      rpc: 26657      # Tendermint RPC endpoint

      grpc: 9090      # gRPC query interface

      exposer: 8081   # Starship exposer service

relayers:
  - name: hermes
    type: hermes
    ports:
      rest: 3000      # Hermes REST API

      exposer: 8081   # Relayer exposer endpoint

explorer:
  enabled: true
  ports:
    rest: 8080        # Block explorer web interface

```

## Running the Port Forward CLI

Execute the connect command to initiate all configured port forwards simultaneously:

```bash
starship connect -c config.yaml

```

Upon successful startup, the CLI outputs structured logs mapping each service to its localhost endpoint:

```

INFO  Port forwarding
INFO  port-forwarding: cosmoshub: rest: to: http://localhost:1317
INFO  port-forwarding: cosmoshub: rpc: to: http://localhost:26657
INFO  port-forwarding: hermes: rest: to: http://localhost:3000
INFO  port-forwarding: explorer: rest: to: http://localhost:8080

```

These endpoints remain accessible until you terminate the process, at which point Starship automatically cleans up all kubectl port-forward subprocesses.

## Implementation Deep Dive

The core port-forward logic resides in [`starship/cmd/starship/connect.go`](https://github.com/hyperweb-io/starship/blob/main/starship/cmd/starship/connect.go), while command registration occurs in [`starship/cmd/starship/root.go`](https://github.com/hyperweb-io/starship/blob/main/starship/cmd/starship/root.go). The implementation leverages the `Config` struct from [`starship/tests/e2e/config.go`](https://github.com/hyperweb-io/starship/blob/main/starship/tests/e2e/config.go) for test-validated configuration parsing.

Key implementation details include:

- **Resource targeting**: The system distinguishes between direct pod access (for specific validators) and service abstraction (for load-balanced explorers)
- **Namespace injection**: Commands automatically include the `-n` flag when `c.config.Namespace` is non-empty
- **Cometmock adaptation**: Automatic port substitution occurs when the configuration specifies cometmock as the RPC backend

Test suites in [`starship/tests/e2e/exposer_test.go`](https://github.com/hyperweb-io/starship/blob/main/starship/tests/e2e/exposer_test.go) and [`starship/tests/e2e/solana_test.go`](https://github.com/hyperweb-io/starship/blob/main/starship/tests/e2e/solana_test.go) demonstrate real-world usage patterns, verifying that forwarded exposer ports correctly proxy chain-specific queries and that Solana nodes remain accessible through the established tunnels.

## Summary

Starship transforms Kubernetes port forwarding from a manual, error-prone process into a declarative, automated workflow:

- Validates `kubectl` availability and pod readiness before attempting connections
- Maps logical service names to well-known ports via the `defaultPorts` configuration
- Constructs precise `kubectl port-forward` commands targeting pods or services
- Executes forwards concurrently with centralized error handling and graceful shutdown
- Maintains connections until user interruption, ensuring stable local access to blockchain infrastructure

## Frequently Asked Questions

### How does Starship handle port conflicts on the local machine?

Starship binds to the exact localhost ports specified in your configuration YAML. If a port is already occupied by another process, the underlying `kubectl port-forward` command fails, and Starship's `RunPortForward()` error propagation mechanism cancels all active forwards. You must free the conflicting port or modify your configuration to use alternative local port numbers before retrying.

### Can I port forward to specific validator pods rather than services?

Yes. The `execPortForwardCmd()` function accepts any valid Kubernetes resource identifier. When targeting specific validators, Starship constructs resource strings like `pods/<chain>-genesis-0` (or the appropriate pod index) rather than service names. This enables direct debugging of individual chain nodes while bypassing any load balancing or service abstraction layers.

### What happens if a blockchain node restarts during an active port forward?

If the target pod terminates or restarts, the underlying kubectl port-forward process exits with an error. Starship detects this failure through the result channel monitoring each goroutine. Upon detecting any forward failure, the system cancels the parent context, which terminates all remaining port-forward processes and returns control to the shell. You must rerun `starship connect` after the pod returns to `Running` status to re-establish connectivity.

### Does Starship support port forwarding for non-blockchain services like explorers?

Absolutely. The `PortForwardCmds()` iterator processes all configuration sections uniformly, including explorers, registries, and relayers. The `defaultPorts` map includes entries for explorer interfaces, and the resource builder correctly formats service targets as `svc/explorer` when generating kubectl commands. This unified approach treats blockchain nodes and auxiliary infrastructure identically from a port-forwarding perspective.