On this page5
  1. Port (`PORT`)
  2. Scratch disk (`/tmp` and `/data`)
  3. Verify before buyer review
  4. Other requirements
  5. Layout
Developers

Web delivery format

Web app delivery requirements: bind PORT (8080), use Velcio's platform health, and ship something the live review can open.

Use Web when the delivery is an HTTP app on https://{slug}.velcio.app, or when it needs inbound webhooks or any public HTTP endpoint.

Workers (no public URL): Delivery format. Worker vs Web: Choosing Worker or Web.

Web means your app binds $PORT. Velcio provides the default GET /healthz. Any framework is welcome, but durable uploads and databases must use external storage because the local filesystem is ephemeral (runtime boundaries).

Port (PORT)

Velcio sets PORT=8080 and sends public HTTPS to that port.

Your process must:

  1. Listen on 0.0.0.0
  2. Bind env PORT (do not hardcode 8000, 3000 or similar)
  3. Use Velcio’s default health endpoint, or implement the custom health path configured for the app

Velcio supplies the default /healthz through its health proxy. You do not need to add that route to your code. A custom app health path must return HTTP 2xx. Before you Send to buyer for review, Velcio checks the public preview’s health.

Do not ship secrets in .env* files. At build time Velcio writes a .dockerignore that excludes .env* (including .env.example). Use Production secrets instead.

Wrong port → public 502 Bad Gateway even when the container looks healthy.

Scratch disk (/tmp and /data)

Read-only root filesystem. Writable space:

PathEnvDefault capUse for
/tmpOS default / TMPDIR64 MB tmpfs, noexecOS temp, Python tempfile, short-lived files
/dataVELCIO_DATA_DIR (/data)~25% of plan RAM (capped 256 MB), noexecScratch / caches during a run

Both are ephemeral: they survive process restarts in the same container, wiped on redeploy. Do not store durable uploads or databases on local disk. VELCIO_DATA_DIR is platform-owned and cannot be overridden via secrets.

Python (Uvicorn):

import os
import uvicorn

port = int(os.environ["PORT"])  # Velcio sets PORT=8080
uvicorn.run("main:app", host="0.0.0.0", port=port)

Node.js:

const port = Number(process.env.PORT || 8080);
app.listen(port, "0.0.0.0");

Verify before buyer review

When deploy is running, open the public URL on the project page and confirm the app works. GET /healthz must return HTTP 2xx on that preview URL. Velcio enforces that check when you Send to buyer for review. If the check fails, inspect app startup, port binding and runtime logs, redeploy if needed, then confirm again. The default platform health route does not need an app implementation.

Revision previews use their own public URL and the same health gate.

After accept, the buyer can rename the subdomain and optionally attach one hostname they already own via CNAME (domain purchased elsewhere). The previous platform hostname keeps working for a 48-hour grace period after a rename. Update webhook and external links before it expires.

Other requirements

  • Build with Auto (buildpacks) or Dockerfile
  • Declare required env var names in Velcio. Never bake secret values into the ZIP.

Layout

Same ZIP / GitHub rules as Delivery format, plus the HTTP contract above.