Skip to content

Routing and Networking

How Requests Reach Your Application

PCF uses Gorouter (a lightweight HTTP router) to direct traffic to applications.

Internet ↓ Load Balancer (external) ↓ Gorouter (multiple instances) ↓ Application Instances

Routes and Domains

Domains

PCF Foundation has one or more domains:

example.com (default domain) apps.example.com (apps domain) api.example.com (API domain)

Each domain points to Gorouter IP (or load balancer frontend).

Routes

Routes are URLs within those domains:

my-app.example.com → Route for my-app my-api.apps.example.com → Route for my-api webhook.api.example.com → Route for webhook

Creating Routes

Routes created automatically on cf push:

```bash $ cf push my-app

Automatically creates route: my-app.example.com

$ cf push my-app --hostname api

Route: api.example.com

$ cf push my-app --domain apps.example.com --hostname my-service

Route: my-service.apps.example.com

```

Route Mapping Model

A single application can have multiple routes:

```bash $ cf push my-app Successfully pushed my-app to: my-app.example.com

Map additional routes

$ cf map-route my-app example.com --hostname old-app $ cf map-route my-app example.com --hostname v2-app

Now all three URLs route to same app:

my-app.example.com → my-app instances

old-app.example.com → my-app instances

v2-app.example.com → my-app instances

```

This enables: - Gradual traffic migration (route old → new) - A/B testing (some requests to v1, some to v2) - Canary releases (small % to new version) - Blue-green deployments (switch between versions)

Load Balancing

Gorouter Round-Robin

Gorouter uses round-robin load balancing:

Request 1 → Instance 0 Request 2 → Instance 1 Request 3 → Instance 2 Request 4 → Instance 0 (cycle)

Sticky Sessions

For session-dependent apps, use sticky sessions:

bash $ cf create-route example.com --hostname my-app $ cf map-route my-app example.com --hostname my-app --random-port

Or configure application-level cookie-based sessions.

Request Flow

1. $ curl my-app.example.com/api 2. DNS resolves: my-app.example.com → Load balancer IP 3. Load balancer forwards to Gorouter 4. Gorouter looks up route table: "my-app.example.com" → [instance0, instance1, instance2] 5. Gorouter picks instance (round-robin): instance1 6. Gorouter connects to instance1:8080 7. Request forwarded to app 8. App processes request 9. Response returned through Gorouter 10. Response sent to client

HTTP Headers

Gorouter adds useful headers:

X-Forwarded-For: 203.0.113.1 # Original client IP X-Forwarded-Proto: https # Original protocol X-Forwarded-Host: my-app.example.com # Original host X-B3-TraceId: abc123 # Trace ID for logging

Your app can use these for logging, security, tracking:

javascript // Node.js const clientIp = req.headers['x-forwarded-for']; const originalProto = req.headers['x-forwarded-proto'];

Networking

Container Network

Each instance runs in isolated container:

``` ┌─ Container 1 ──────┐ │ App listening:8080 │ │ IP: 10.0.0.5 │ └────────────────────┘

┌─ Container 2 ──────┐ │ App listening:8080 │ │ IP: 10.0.0.6 │ └────────────────────┘ ```

Applications listen on $PORT (usually 8080):

bash export PORT=8080 node app.js

Egress (Outbound Connections)

Applications can make outbound connections:

javascript // Node.js making outbound call const response = await fetch('https://external-api.com/data');

Network policies restrict which destinations are allowed:

```bash cf add-network-policy my-app my-cache-app --protocol tcp --port 6379

my-app can now access my-cache-app on port 6379

```

Service Binding Network

When bound to service, app connects via injected credentials:

Application → Environment Variables → DATABASE_URL=postgres://host:5432/db → Application code makes connection → Network policy permits → Connected to database

Blue-Green Deployments

PCF makes blue-green deployments straightforward via routes:

Setup Blue Instance

bash $ cf push my-app-blue Created route: my-app-blue.example.com Bound to: my-app-blue

Deploy Green Instance

bash $ cf push my-app-green Created route: my-app-green.example.com Bound to: my-app-green

Switch Traffic

```bash

Both versions running separately:

my-app-blue.example.com → Blue (v1)

my-app-green.example.com → Green (v2)

Map main route to green:

$ cf map-route my-app-green example.com --hostname my-app

Test against green:

$ curl my-app-green.example.com

Once verified, unmap from blue:

$ cf unmap-route my-app-blue example.com --hostname my-app

Traffic now at:

my-app.example.com → Green (v2)

Blue remains available for rollback:

$ cf map-route my-app-blue example.com --hostname my-app ```

Advanced: Custom Domains

Add Domain to Foundation

```bash

Operators add domain:

cf create-domain my-org example.com ```

Map Route with Custom Domain

```bash $ cf push my-app --domain example.com --hostname my-service

Route: my-service.example.com

```

Wildcard DNS

DNS configuration:

*.example.com CNAME elb.cloud-foundry.example.com

All routes automatically work without DNS entries.

Security Considerations

HTTPS / TLS

  • Gorouter terminates TLS
  • Connections to instances are HTTP
  • Certificate management handled by platform

Internet (HTTPS) ↓ (TLS termination at Gorouter) Gorouter (HTTP) ↓ (Internal network) App Instances (HTTP :8080)

Ports

  • Applications must listen on $PORT
  • Only port 8080 exposed by default
  • Cannot listen on privileged ports (<1024)
  • One application per port

Next: Scaling & Availability