Service types
Each entry under services: has a type. A single entity can contain several
services (an API, a frontend, a worker, a cron) — each gets its own build, its own
port, and its own route prefix.
Your code lives under services/<service-name>/.
An Express/HTTP Node.js service. Listen on process.env.PORT.
name: my-apiservices: api: type: node path: /const PORT = process.env.PORT || 8080;require('http') .createServer((req, res) => res.end('ok')) .listen(PORT);For TypeScript, add lang: typescript — the build expects src/index.ts and a
tsconfig.json, and compiles with tsc.
services: api: type: node lang: typescript path: /nextjs
Section titled “nextjs”A Next.js app. Set standalone output in next.config.mjs:
/** @type {import('next').NextConfig} */export default { output: 'standalone' };name: my-dashboardservices: web: type: nextjs path: /The platform builds with npm run build and runs the standalone server — no
Dockerfile needed. Build-time public vars go under the service’s build.env.
python
Section titled “python”A Python service. Dependencies go in services/<name>/requirements.txt, installed
during build.
name: my-serviceservices: worker: type: python path: /import osfrom http.server import HTTPServer, BaseHTTPRequestHandlerPORT = int(os.environ.get('PORT', 8080))HTTPServer(('', PORT), BaseHTTPRequestHandler).serve_forever()static
Section titled “static”A static site served over HTTP. Place your index.html at the service root.
name: landing-pageservices: site: type: static path: /For a static site with a build step (Vite, Astro, and similar), declare a
build: block. The platform runs the command and serves the output directory:
services: site: type: static path: / node_version: "22" build: command: "npm run build" output: "dist" env: VITE_API_URL: "https://my-api.your-grid.cloudgrid.io"node_version accepts "18", "20", "22", or "24" (default "22"), and
applies to the static build step.
A scheduled job. Requires a schedule and cannot have a path or port.
services: cleanup: type: cron schedule: "0 3 * * *" # daily at 3am timezone: UTC run: job # default: runs src/job.js or src/main.pyFor HTTP-triggered cron (no code in your repo), point run at a URL:
services: ping: type: cron schedule: "*/5 * * * *" run: "https://my-api.your-grid.cloudgrid.io/cron/ping"Multi-service apps
Section titled “Multi-service apps”name: my-platformservices: api: type: node path: /api web: type: nextjs path: / cron: type: cron schedule: "0 */6 * * *" run: jobneeds: database: true cache: trueUse path: to route traffic; set path: false for internal-only services. Use
depends_on: to order startup. During grid dev, each service receives sibling
URLs as environment variables so they can call each other locally.