Multi-Service Apps (compose-style)

One app can run several containers — e.g. a web frontend plus an internal cache or database. It’s the platform’s take on a Compose stack: 1 app = N services, but it still counts as one unit against your quota.

Rules

  • Provide a services array (at least one).
  • Exactly one service must be public: true — it gets the app’s HTTPS domain.
  • Internal services (public:false) are not exposed to the internet. They live on a private per-app network and are reachable by other services by their name (e.g. http://cache:6379).
  • Each service can use its own image, or build from a shared top-level repo.
  • repo / branch / repoToken stay at the app level (one repo for the stack); port / env / cpu / memory / secrets are per service.

Example — public web + internal redis

curl -s -X POST $API/deploy \
  -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{
    "name": "shop",
    "services": [
      { "name": "web",   "image": "acme/storefront:1.0", "port": 8080, "public": true,
        "env": { "REDIS_URL": "redis://cache:6379" } },
      { "name": "cache", "image": "redis:7-alpine",      "port": 6379, "public": false }
    ]
  }'
  • https://shop.cynchro.cloud → the web container.
  • web reaches cache over the private network at redis://cache:6379.
  • cache is invisible from the internet.

Service fields

Field Required Notes
name DNS-safe; also the internal hostname.
image ✅* Prebuilt image, OR omit to build from the app-level repo.
dockerfile / context   When building from repo (relative paths).
port   Default 80. Port the service listens on.
public   true for the one internet-facing service.
domain   Override the public service’s hostname.
cpu / memory   Per-service limits.
env   Per-service env (encrypted at rest).
envFrom / secretFiles   Per-service Secrets references.

* Each service needs either its own image or a top-level repo to build from.

Building all services from one repo

-d '{
  "name": "stack",
  "repo": "https://github.com/acme/monorepo",
  "services": [
    { "name":"api", "dockerfile":"api/Dockerfile",  "context":"api",  "port":3000, "public":true },
    { "name":"worker", "dockerfile":"worker/Dockerfile", "context":"worker", "port":0, "public":false }
  ]
}'

The repo is cloned once and each service is built from its own Dockerfile.

Lifecycle

Restart / stop / delete act on the whole app (all its containers). Deleting also tears down the private network. Self-healing watches every container — if any dies, the app is redeployed.

→ Back to basics: Deploy from Git · Inject config: Secrets


This site uses Just the Docs, a documentation theme for Jekyll.