Skip to main content

App Hosting Overview

App Hosting lets you deploy a public OCI container image on a dedicated VM, reachable over HTTPS at https://{name}.foundrydb.com, and optionally wired directly to your managed databases over a private SDN network. Your app and its data run in the same region, on the same private backbone, with no public traffic between them.

What App Hosting provides

CapabilityWhat it does
Dedicated VM per appYour container gets its own VM, not a shared slice. Resource accounting is honest and the failure domain stays small.
HTTPS at {name}.foundrydb.comA platform-issued certificate is provisioned before the container serves its first request. No ingress controller to configure.
Private database networkingAttach up to five managed databases. The platform peers the networks, opens the firewall, and injects connection credentials as environment variables.
Blue/green deploysA new image or environment change starts the new container alongside the old one. Traffic only cuts over once the new container is healthy. A failed redeploy leaves the previous container serving.
Build from sourcePoint the app at a git repository with a Dockerfile. The platform clones, builds on the app's own VM, pushes to the private platform registry, and deploys the image by digest.
Deploy history and rollbackEvery successful deploy is recorded as an immutable revision. Roll back to any revision with a single API call.
Custom domainsBring your own hostnames. Certificates are issued and renewed automatically.
App-to-app private networkingAttach one app to another. Traffic stays on the private SDN; the target's host, port, and URL are injected as environment variables.

How it works

Each app runs as a single OCI container on its own VM, managed by a systemd Quadlet unit under Podman. A Caddy HTTPS ingress terminates TLS and proxies to the container port on the VM loopback. The container port is never exposed publicly.

Internet → Caddy (TLS) → container port (loopback) → your app
↕ private SDN
attached databases / apps

A deploy works like this: the platform starts the new container alongside the old one, probes it on its health check path, and cuts the ingress over only once it returns the required number of consecutive 2xx responses. If the probe never goes green within the timeout, the deploy fails and the old container keeps serving.

Lifecycle, end to end

The diagram below traces an app from the create call through to steady-state serving, then loops back through the blue/green redeploy that every subsequent change runs.

App container lifecycle
Running · Ingress serving :443
CreatePOSTPendingqueuedProvisioningVM · node · ingressPull + startcontainer runtimeRunningserving↑ serve :443Ingress:443 HTTPS
CreatePendingProvisioningPull / RunningIngress :443blue/green redeploy

The flow has three stretches:

  1. Bring-up. The POST is accepted and the app sits in Pending. Provisioning then sets up the dedicated VM and its disks, installs the agent that executes work on the VM, and configures the Caddy ingress (including issuing the TLS certificate for {name}.foundrydb.com). These steps run on one VM and converge before the container starts.
  2. First run. The agent pulls the container image and starts it under a Podman Quadlet unit. Once the container is up and healthy, the app reaches Running and Caddy begins terminating TLS on :443 and proxying to the container on the loopback.
  3. Steady state and redeploys. While Running, Caddy serves traffic. Any later change (new image, env, configuration, or attachment) re-enters the pull-and-start step as a blue/green redeploy: the new container is brought up alongside the current one and only takes over once it is healthy.

Runtime model

  • One container per VM. Each app is a single OCI container on its own dedicated VM. There is no shared host, no multi-replica scaling, and no orchestration layer between you and the container.
  • Podman Quadlet. The container is declared as a systemd Quadlet unit and run by Podman. systemd owns the container's lifecycle on the VM, so it is started on boot, restarted on exit, and managed like any other unit.
  • Caddy ingress. A Caddy process on the VM terminates TLS and reverse-proxies to the container port over the loopback interface. The container port is bound to localhost and is never published on the public interface. Caddy is also where blue/green cutover happens: pointing ingress at the new container is what makes a deploy live.
  • Private database and app networking. When you attach a managed database or another app, traffic to it stays on the private SDN. The platform peers the networks, opens the firewall, and injects the connection details (and credentials) into the container as environment variables. No attached traffic crosses the public Internet.
  • Stateless by default. An app's durable state lives in its attached databases. The container itself is treated as replaceable: each redeploy starts a fresh container from the image.

When to use App Hosting

App Hosting is a good fit for:

  • API servers, background workers, or web apps that read from or write to managed databases
  • Apps where you want database credentials, firewall rules, and network peering managed for you
  • Services you want to redeploy frequently with zero downtime
  • Internal services that need to call each other over a private network

It is not a general-purpose container runtime. Each app is one image on one VM. There is no multi-replica horizontal scaling, no container orchestration, and no persistent volume management (apps are stateless beyond their attached databases).

Minimal example

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": "docker.io/traefik/whoami:latest",
"container_port": 80
},
"storage_size_gb": 10
}'

Provisioning is asynchronous. Poll GET /app-services/{id} until status is Running. The response then includes the public url.

App lifecycle

An app moves through a small set of statuses. Provisioning and redeploys are asynchronous, so the status is how you track progress: poll GET /app-services/{id} and watch it settle on Running (or Failed).

StatusMeaningWhat is happening
PendingAccepted, waiting for network and VM provisioning to start.The create call has been recorded and the app is queued. Nothing is serving yet.
PendingModificationA redeploy, scale, or attachment change is in progress.The same state covers both first-time provisioning (VM, agent, ingress, certificate, then image pull and start) and later changes. During a redeploy the current container keeps serving until the new one is healthy.
RunningContainer is serving.The container is up and healthy, Caddy is terminating TLS on :443, and the public url is live. This is the steady state.
StoppedContainer is stopped.The container has been stopped and is not serving. The VM, ingress configuration, and attachments are retained so it can be started again.
DeletingTeardown in progress.The platform is removing the container, ingress, certificates, DNS records, and the VM.
FailedProvisioning or redeploy failed.A bring-up step or a health-gated redeploy did not complete. On a failed redeploy the previously healthy container keeps serving and the app holds the previous revision.

Next steps