Apps

Any container image or Git repository, kept running, deployed without downtime.

Overview

An app is a program that runs all the time: a website, an API, a worker. You give EnclaveStack a container image, or a Git repository with a Dockerfile, and it keeps the app running, restarts it when it stops and deploys every change without taking it down.

Apps get settings as environment variables, secrets decrypted at start, private names other resources reach them by, and, with a domain, a web address with HTTPS.

When to use it

  • A website or API to put online.
  • A worker that reads from a queue.
  • Several copies of a service behind one name.
  • Code in a Git repository you want built and run on push of a button.

How it works

Docker Engine
Each copy of an app is a container on the machine’s Docker Engine, driven through its API.
Revisions
Every deploy is a numbered revision (es-app-<name>-r<N>); revisions share the app’s private name.
Health probes
HTTP, TCP or command checks run before a new revision takes traffic.
Builds from Git
A shallow clone (go-git) built through the engine’s build API, tagged per revision.
Caddy edge
Domains reach the app through the edge proxy, which follows the app’s replicas.

You describe the app; the control plane stores it and the reconciler makes it real. Each change becomes a new revision: its containers start next to the serving ones, health checks must pass, then traffic switches, the old revision drains and stops.

A revision is 1 – 10 replicas. All of them answer to the app’s private name (<name>.app.internal), so other resources and the edge spread requests across them. Publishing binds one host port on this machine instead.

Secrets named in the app are decrypted from the store at deploy time and handed to the containers as environment variables; they never appear in the API, events or logs.

Architecture

Apps architectureA rolling deploy: the edge and other resources reach the app by its stable name while a new revision starts, passes its health check and takes over.HTTPSproxyby namemountenvVisitorhttps://shop.example.comOther resourcesjobs, appsEdge (Caddy)HTTPS, domainsPrivate nameweb.app.internalRevision r1serving · 2 replicasRevision r2health-checked, thenswitchedVolumefiles kept acrossdeploysSecretsdecrypted into env atstart
A rolling deploy: the edge and other resources reach the app by its stable name while a new revision starts, passes its health check and takes over.
  • Visitor to Edge (Caddy): HTTPS
  • Edge (Caddy) to Revision r1: proxy
  • Other resources to Private name: by name
  • Private name to Revision r1
  • Revision r1 to Volume: mount
  • Secrets to Revision r2: env

Flows

Deploying a change

  1. You change the image, a setting or press Redeploy.
  2. The reconciler starts revision N+1 next to the serving one, with the same name and mounts.
  3. Each new replica must pass its health check; if it never does, it is discarded and revision N keeps serving.
  4. Traffic switches to N+1; revision N drains for a few seconds, then stops.

A request from the internet

  1. The visitor’s browser connects to the edge on port 443 with the domain’s certificate.
  2. The edge proxies to the app’s private name, which answers with every healthy replica.
  3. The app answers through the edge.

Building from Git

  1. The control plane clones the branch, tag or commit you chose.
  2. The engine builds the Dockerfile from the build context.
  3. The image is tagged for the revision and deployed as above; the build log is kept on the app.

Set it up

In the console

  1. Open Apps and choose New app.
  2. Give it a name, an image (or a Git repository) and the port it listens on.
  3. Turn on Publish to reach it from this computer, or add a domain later.
  4. Choose Create and watch Pull, Start, Health and Switch.

With the CLI

enclave app create web --image nginx:1.27-alpine --port 80 --publish --wait

With OpenTofu

OpenTofu configuration
resource "enclave_app" "web" {
  name    = "web"
  image   = "nginx:1.27-alpine"
  port    = 80
  publish = true
}

Settings reference

Every setting and output of the OpenTofu resource; the console and the CLI use the same names in their own words. Generated from platform 4d30582.

enclave_app
NameTypeUseWhat it does
nametextrequiredName of the app: 3–40 lowercase letters, digits or hyphens, starting with a letter. Changing it replaces the app.
commandlist of textoptionalReplaces the image's command.
envmap of textoptionalPlain environment variables.
health_checklist of objectsoptionalWhen a new revision may take traffic. Unset: tcp on the port, or 5 s running without restarts.
imagetextoptionalContainer image, e.g. nginx:1.27-alpine. Exactly one of image or source.
machinetextoptionalThe machine to run on (default: EnclaveStack chooses, and this reads back its choice). Changing it moves the resource, with its data, in place; apply waits for the move.
machine_labelsmap of textoptionalLabels the machine must have, when machine isn't set (key=value, all must match).
memory_mibnumberoptionalMemory limit in MiB (64–16384).
networktextoptionalNetwork to place it in (default: the default network). Changes in place.
portnumberoptionalPort the app listens on.
projecttextoptionalThe project to create it in. Defaults to the provider's project (ENCLAVE_PROJECT, else default). Changing it replaces the resource.
publishtrue or falseoptionalPublish the port on the host (requires port).
replicasnumberoptionalContainers per revision (1–10); a published app runs one.
secret_envmap of textoptionalEnvironment variables taken from secrets: variable name → secret name.
sourcelist of objectsoptionalBuild the app from a Git repository and its Dockerfile (BuildKit). Exactly one of image or source. A redeploy builds the ref's latest commit.
strategytextoptionalrolling: a new revision takes traffic only once healthy; recreate: stop, then start. Published apps always recreate.
subnettextoptionalSubnet of the network (default: its first).
volumeslist of objectsoptionalFilesystem volumes mounted into every container; a change deploys a new revision.
built_committextoutputThe commit the serving revision was built from (source apps).
hosttextoutputHost to reach a published app from this machine.
host_portnumberoutputPort to reach a published app from this machine.
idtextoutputResource ID.
internal_hosttextoutputHost other apps use on the EnclaveStack network.
internal_portnumberoutputPort other apps use on the EnclaveStack network.
private_dnstextoutputName the app answers to inside its network: <name>.app.internal.
private_iptextoutputThe serving revision's address in its network.
serving_revisionnumberoutputThe revision receiving traffic.

Limits and security

Good to know

  • 1 – 10 replicas per app; a published app runs one.
  • Memory is reserved per replica (256 MiB unless you choose).
  • Build arguments are not for secrets; use secret environment variables.

Security

  • Never privileged, never on the host network, never with host folders mounted.
  • Secrets reach the app only as environment variables at start.
  • A firewall can limit who may connect to it.