Skip to main content

Deploy an App

An app service is created with a single POST /app-services request. The platform provisions the VM, installs and starts the container, sets up the HTTPS ingress and DNS, and drives the app from Pending to Running asynchronously.

Deploy from a git repository

An app can start from a prebuilt image (this page) or from source: point app_config.source at a git repository with a Dockerfile and the platform clones, builds, and deploys it through the same blue/green flow. See Build from Source. Everything else on this page (plans, health checks, updates, deletion) applies to both kinds of app.

Create an app

curl -u "$USER:$PASS" -X POST https://api.foundrydb.com/app-services \
-H "Content-Type: application/json" \
-d '{
"name": "my-api",
"plan_name": "tier-2",
"zone": "se-sto1",
"app_config": {
"image_ref": "ghcr.io/acme/api:1.0.0",
"container_port": 8080,
"env": {
"LOG_LEVEL": "info",
"CACHE_TTL": "300"
}
},
"storage_size_gb": 10
}'

The response is 201 Created with the app in Pending. Poll until Running:

curl -u "$USER:$PASS" https://api.foundrydb.com/app-services/{id}

Once Running, the response includes the url field, for example https://my-api-ab12cd34.foundrydb.com.

Request fields

Top-level

FieldRequiredDescription
nameYesName for the app. Becomes part of the foundrydb.com hostname.
plan_nameYesCompute tier. tier-2 (2 vCPU, 4 GB RAM) is a good default.
zoneNoUpCloud zone. Defaults to se-sto1 (Stockholm). Must share a peering region with any attached databases.
app_configYesContainer configuration (see below).
storage_size_gbNoVM disk size in GB. Minimum 10, default 10.
storage_tierNostandard or maxiops (NVMe SSD). Default maxiops.
attached_service_idsNoUUIDs of managed databases or apps to attach at creation. Up to five.

app_config

FieldRequiredDefaultDescription
image_refYesFull OCI image reference, for example docker.io/library/nginx:1.27.
container_portYesTCP port the container listens on. Cannot be changed after creation.
envNo{}Environment variables. Keys must be valid POSIX names and must not start with MDB_ or equal DATABASE_URL.
custom_domainsNo[]Additional hostnames beyond {name}.foundrydb.com. Up to five.
registry_usernameNoUsername for a private registry. Provide with registry_password.
registry_passwordNoPassword or access token. Write-only: never returned by the API.
health_check_pathNo/HTTP path probed on the new container during a blue/green deploy. Must return 2xx.
health_check_interval_secondsNo2Seconds between probe attempts.
health_check_timeout_secondsNo120Seconds to wait for the container to become healthy before the deploy fails.
health_check_healthy_thresholdNo1Consecutive 2xx responses required before traffic cuts over.

Compute plans

PlanvCPUMemory
tier-112 GB
tier-224 GB
tier-448 GB
tier-6616 GB

Prefer tier-2, tier-4, or tier-6. See Scaling and Health for resize behaviour.

Configuring health checks

Health checks gate the blue/green deploy cutover. A container that never becomes healthy within the timeout fails the deploy, and the previous container keeps serving with no interruption.

curl -u "$USER:$PASS" -X POST https://api.foundrydb.com/app-services \
-H "Content-Type: application/json" \
-d '{
"name": "my-api",
"plan_name": "tier-2",
"zone": "se-sto1",
"app_config": {
"image_ref": "ghcr.io/acme/api:1.0.0",
"container_port": 8080,
"health_check_path": "/healthz",
"health_check_timeout_seconds": 60,
"health_check_healthy_threshold": 3
}
}'

The probe runs on the VM loopback against the container's own port, so it does not depend on public DNS or TLS.

Update and redeploy

Zero-downtime blue/green cutover
CUTOVER GREEN serving · BLUE drained
Ingress:443ingress →Green:18081⇢ SDNPostgreSQL:5432
Ingress proxyBlue (active)Green (deploying)PostgreSQL :5432App B (east-west)private SDN (dashed)

A PATCH /app-services/{id} replaces app_config wholesale and triggers a zero-downtime blue/green redeploy if image_ref, env, or custom_domains changed. Send the full desired config including any fields you want to keep.

Every redeploy follows this sequence:

  1. Image pull. The platform pulls the new image_ref from the registry before stopping the live container. If the pull fails (missing tag, bad credentials, registry unreachable), the deploy is aborted and the running container is untouched.
  2. Container start and health probe. The new container starts on the same VM alongside the existing one. The platform probes health_check_path on the container's port over loopback, repeating every health_check_interval_seconds until health_check_healthy_threshold consecutive 2xx responses are received or health_check_timeout_seconds elapses.
  3. Ingress cutover. Once the new container passes its health threshold, the nginx ingress rule is atomically rewritten to route traffic to the new container. Existing connections to the old container are allowed to finish.
  4. Old container drain and stop. After cutover the old container receives a SIGTERM and is given a short grace period to drain in-flight requests, then is stopped and removed.

A deploy that fails the health check leaves the old container running. The app stays Running and the failed deploy is recorded in the deployment history without any user-visible downtime.

curl -u "$USER:$PASS" -X PATCH https://api.foundrydb.com/app-services/{id} \
-H "Content-Type: application/json" \
-d '{
"app_config": {
"image_ref": "ghcr.io/acme/api:1.1.0",
"container_port": 8080,
"env": { "LOG_LEVEL": "debug" },
"health_check_path": "/healthz"
}
}'

Note: container_port cannot be changed after creation. The app must be Running to accept a PATCH.

Delete an app

curl -u "$USER:$PASS" -X DELETE https://api.foundrydb.com/app-services/{id}

Deletion tears down the container, ingress, certificates, DNS records, floating IP, attachment peerings and firewall openings, and the VM. A database that still has apps attached cannot be deleted until those apps are removed.

Dashboard

The app detail page in the dashboard covers the same lifecycle. The Overview tab shows current status and the public URL. The Configuration tab lets you update the image and environment. The Deployments tab shows the deploy history.