Skip to main content

Overview

The launch page gets its backend. The quickstart API is built from source like the frontend and runs as a workload with no public endpoint. The frontend reaches it the way workloads reach each other on Control Plane, over an internal endpoint the service mesh encrypts with mTLS using certificates it manages for you, and only once the API’s firewall names the frontend as a caller. That is the zero-trust shape a production backend wants, and you will watch the default deny block the first call before you allow it. What you’ll build:
  • A container image of the quickstart API in your org’s private registry.
  • An api workload in quickstart-gvc, reachable only over the internal network.
  • The frontend workload calling api, allowed by api’s internal firewall, with the waitlist open.
Inside the GVC quickstart-gvc, the workload frontend calls the workload api at api.quickstart-gvc.cpln.local:8080 over the internal network, encrypted by the mesh. frontend keeps its public endpoint and api has none, and api admits frontend by name on its internal firewall. Two workloads talk inside the GVC; the API answers only the callers its firewall names.
Workloads reach each other through internal endpoints of the form:
The receiving workload’s internal firewall decides who may connect. A new workload starts with none, so no other workload reaches it, not even one in the same GVC. The API keeps that default until you name frontend on its workload list.

Prerequisites

  • Completed 2. Deploy your own application with the frontend workload running.
  • The CLI installed and logged in, as in part 2, to build the API’s image.

Step 1: Download the API

macOS / Linux

Downloads api.tgz, a gzipped tar archive.

Windows

Downloads api.zip, the same source as a zip archive.
Extract the archive and navigate to the directory:
The API is a Node.js service with three routes, all in src/server.ts: It keeps the signups in memory. Part 4 gives it a database.

Step 2: Build and push the image

The command ends by printing the image it pushed, your-org.registry.cpln.io/api:1.0 where your-org is the name of your org, together with its link. Workloads reference it as //image/api:1.0.

Step 3: Create the API workload

1

Navigate to Workloads

With quickstart-gvc as the current context, click Workloads in the left menu, then click New.
2

Configure basic settings

Enter api as the name and make sure quickstart-gvc is the selected GVC.
3

Configure the container

Click Containers in the left pane and keep Control Plane as the image source. In the image dropdown, type api and select api:1.0. Under Ports, keep protocol http and number 8080.
4

Create it with the firewall closed

Click Create. A new workload has no public endpoint, and under Firewall, Internal, its Inbound Allow Type is None: nothing reaches it yet.

Step 4: Point the frontend at the API

1

Add the environment variable

Open the frontend workload, click Containers in the left pane, and open the Env Vars tab. Click Add Environment Variable, enter API_URL as the Name, keep Literal Value as the value type, and enter http://api.quickstart-gvc.cpln.local:8080 as the value.
2

Update

Click Update. The workload rolls out a new version.

Step 5: See the default deny

Wait until frontend reports Ready again, then open its canonical endpoint. The page waits for its call to the API to time out, then reports below the waitlist form: Could not reach the API at http://api.quickstart-gvc.cpln.local:8080: no answer within 3 seconds. The name resolves and the connection is never answered, because api admits no caller yet.

Step 6: Allow the frontend

1

Open the API's internal firewall

Open the api workload, click Firewall in the left pane, then Internal.
2

Switch to a workload list

Set Inbound Allow Type to Workload List. Under Inbound Allow List, click Add Workload, select frontend, and confirm.
3

Update

Click Update.

Verify

Once api reports Ready again, reload the frontend (a 503 from the API means the mesh is still switching to the new version, so reload once more). The form is enabled and the note reads Be the first on the list. Join with an email address. The form answers You're on the list as you@example.com., the note becomes 1 person is already waiting., and Recent signups lists the address, with the badge next to its heading reading, for the location nearest to you, Stored in memory by api in aws-us-west-2. Open the other location’s endpoint from the Deployments page (or cpln workload get-deployments frontend --gvc quickstart-gvc, or by asking your AI agent for it). It still reads Be the first on the list. with No signups yet., because the frontend’s call stays in its own location and each API replica keeps its own memory. Part 4 gives them one database.
Two workloads communicate over the internal network, encrypted with mTLS, with access granted by the receiving workload’s firewall, and the API has no public endpoint at all.

Internal firewall options

The workload-list option requires view permission on the allowed workloads.

What you’ve learned

  • Closed by default: a new workload admits no internal caller until its firewall names one, and without a public endpoint it is invisible from the internet.
  • Internal endpoints use the .cpln.local domain, resolve from every workload in the org, and work across GVCs.
  • Calls stay local: a call to an internal endpoint is served by the replica in the caller’s own location whenever one is ready there.
  • One build path for every service: the API went from source to a running workload with the same cpln image build and the same workload creation as the frontend.

Next steps

4. Add a database and wire its secret

Give the API a PostgreSQL database from the Template Catalog, with its credentials delivered through an identity, a policy, and a secret reference.

Clean up

To remove everything the series has created so far:
1

Delete the GVC

Open quickstart-gvc, click Actions, then Delete, type the GVC name to confirm, and click Delete. web, frontend, and api go with it.
2

Delete the images

Open Images, select frontend, and click Actions, then Delete to remove all its tags. Repeat for api.
A --remote build also pushes the build cache images frontend-cache:latest and api-cache:latest; delete those too if you built without Docker.