Skip to content

Stack with dependencies

A stack is a single YAML file containing multiple kind: Application documents separated by ---, with metadata.dependsOn declaring the order. edgible stack deploy resolves the graph and applies each application in order.

Use this when you have separate applications that need to be deployed together — for example, a database, an API, and a web frontend, where the API must be up before the frontend can start.

This shape (multiple applications, joined by metadata.dependsOn):

metadata:
name: api
dependsOn: [db]

versus this shape (one application with multiple workloads, joined by workload-level dependsOn):

workloads:
- name: db
type: compose
composeFile: ./db.yml
- name: api
type: compose
composeFile: ./api.yml
dependsOn: [db]

Choose multi-workload when the pieces are tightly coupled — they always deploy together, share a lifecycle, and live on the same device. Choose a stack when the pieces are loosely coupled — different teams own them, they can be updated independently, and they may live on different devices.

Save as stack.yml:

stack.yml
apiVersion: v3
kind: Application
metadata:
name: stack-db
organization: <your-org-id>
spec:
placement:
strategy: serving-device
deviceSelector: { deviceName: my-server }
workloads:
- name: db
type: compose
composeFile: ./docker-compose-db.yml
ports:
- { name: pg, containerPort: 5432, protocol: tcp }
access:
- name: pg
type: tcp
target: { workload: db, port: pg }
listenPort: 5432
publish: false
---
apiVersion: v3
kind: Application
metadata:
name: stack-api
organization: <your-org-id>
dependsOn: [stack-db]
spec:
placement:
strategy: serving-device
deviceSelector: { deviceName: my-server }
workloads:
- name: api
type: compose
composeFile: ./docker-compose-api.yml
ports:
- { name: http, containerPort: 8080, protocol: tcp }
access:
- name: api
type: https
target: { workload: api, port: http }
hostname: { custom: api.example.com }
tls: { managedBy: edgible }
policies: { auth: { mode: api-key } }
---
apiVersion: v3
kind: Application
metadata:
name: stack-web
organization: <your-org-id>
dependsOn: [stack-api]
spec:
placement:
strategy: serving-device
deviceSelector: { deviceName: my-server }
workloads:
- name: web
type: compose
composeFile: ./docker-compose-web.yml
ports:
- { name: http, containerPort: 3000, protocol: tcp }
access:
- name: web
type: https
target: { workload: web, port: http }
hostname: { custom: app.example.com }
tls: { managedBy: edgible }
policies: { auth: { mode: edgible-login } }

The db application has a tcp access entry with publish: false — it’s reachable from other workloads in the same device pool over the WireGuard mesh, but not from the public internet.

Terminal window
edgible stack deploy -f stack.yml

The CLI:

  1. Reads every kind: Application document in the file.
  2. Builds a topological order from metadata.dependsOn.
  3. Applies them in order: stack-dbstack-apistack-web.
  4. Waits for each to reach ready before moving to the next.

If the graph contains a cycle, validation rejects the file before any deploy.

Terminal window
edgible stack status -f stack.yml

Shows status across all applications in the file as a single view.

Terminal window
edgible stack diff -f stack.yml

Shows what would change if you applied the file as-is — useful for reviewing changes before deploy.

Terminal window
edgible stack validate -f stack.yml

Checks the file against the schema and the dependency graph without contacting the control plane.

Terminal window
edgible stack teardown -f stack.yml

Removes every application in the file in reverse-dependency order: stack-webstack-apistack-db. Storage attached to any application is released as that application is removed.

Nothing forces every application in a stack to share a placement. The same file can put the database on a serving device you own and the API in cloud:

metadata: { name: stack-db, ... }
spec:
placement: { strategy: serving-device, deviceSelector: { deviceName: my-server } }
...
---
metadata:
name: stack-api
dependsOn: [stack-db]
spec:
placement: { strategy: cloud, region: us-east-1 }
...

Useful for keeping data on hardware you control while putting the public-facing tier in cloud.