Zaroz
Workload guides

Add a public port to a Workload

Continues from Deploy a Workload from a public image. It uses the api helper from that guide, plus PROJECT_ID and SERVICE_ID. Read Public ports and HTTPS endpoints to choose between the two kinds.

TerminalCode
export EP="$ZAROZ_API/projects/$PROJECT_ID/service-instances/$SERVICE_ID/endpoints"

API status

The endpoint routes are used by the console and are tagged console-only in the API reference. They accept your session token or a personal access token.

A raw TCP or UDP port

Say which port your app listens on inside the container (internal_port) and which protocol. Zaroz assigns the public address and number.

TerminalCode
curl -s -X POST "$EP" \ -H "Authorization: Bearer $ZAROZ_TOKEN" -H "Content-Type: application/json" \ -d '{"kind":"port","internal_port":25565,"protocol":"tcp"}'
TypeScriptCode
const base = `/projects/${projectId}/service-instances/${serviceId}/endpoints`; const port = await api("POST", base, { kind: "port", internal_port: 25565, protocol: "tcp" }); console.log(`${port.public_ip}:${port.public_port}`, port.state);
Code
base = f"/projects/{project_id}/service-instances/{service_id}/endpoints" port = api("POST", base, {"kind": "port", "internal_port": 25565, "protocol": "tcp"}) print(f"{port['public_ip']}:{port['public_port']}", port["state"])

The response carries id, public_ip, public_port and state (active once open). Use "protocol": "tcp_udp" for one public number on both protocols. Raw ports are billed by the hour they are held; a Workload's plan includes none free (see Billing).

If the service is not running yet, the request is refused with not_ready. Wait for the deployment, then retry.

A free HTTPS endpoint for a website or API

Your app serves plain HTTP on internal_port; Zaroz handles TLS.

TerminalCode
curl -s -X POST "$EP" \ -H "Authorization: Bearer $ZAROZ_TOKEN" -H "Content-Type: application/json" \ -d '{"kind":"https","internal_port":80,"label":"my-web"}'
TypeScriptCode
const site = await api("POST", base, { kind: "https", internal_port: 80, label: "my-web" }); console.log(site.https); // the host, and any domains
Code
site = api("POST", base, {"kind": "https", "internal_port": 80, "label": "my-web"}) print(site["https"])

label is optional and picks the first part of the free host, <label>.zone.<zone>.zaroz.cloud. To serve your own domains too, send "domains": ["www.example.com"]; each must be a domain your organization has verified, or a subdomain of one. If one is refused, nothing opens.

List and close

TerminalCode
curl -s "$EP" -H "Authorization: Bearer $ZAROZ_TOKEN" | jq '.data[] | {id, kind, state, public_ip, public_port}' curl -s -X DELETE "$EP/$ENDPOINT_ID" -H "Authorization: Bearer $ZAROZ_TOKEN" -w "%{http_code}\n"
TypeScriptCode
const list = await api("GET", base); for (const e of list.data) console.log(e.id, e.kind, e.state, e.public_ip, e.public_port); await api("DELETE", `${base}/${port.id}`); // 204; closing a closed port also succeeds
Code
for e in api("GET", base)["data"]: print(e["id"], e["kind"], e["state"], e.get("public_ip"), e.get("public_port")) api("DELETE", f"{base}/{port['id']}") # 204; closing a closed port also succeeds

The list shows pending ports first, then every port the service ever held, newest first. A closed port stays listed with its last address so you can match a month's invoice against it. Closing stops billing from that moment.

When it is refused

The details of a refusal begins with a code before the colon: port_limit, port_in_use, no_address_available, no_port_available, internal_port_out_of_range, protocol_required, and for HTTPS host_taken, domain_not_verified and others. The full list is in Public ports and HTTPS endpoints.

A port goes to one unit. If you run several units and need a public address for each, see Public ports and Private names.

Last modified on