Workflows

Framework Examples

Node.js (Express)

grid init app my-api --type node

Scaffolded structure:

my-api/
  cloudgrid.yaml
  services/
    api/
      package.json
      src/
        index.js
      .env.example
  .cloudgrid/
    link.json       # gitignored

cloudgrid.yaml:

name: my-api
services:
  api:
    type: node
    path: /
requires:
  - db
  - redis

services/api/src/index.js:

const http = require('http');

const PORT = process.env.PORT || 3000;

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({ status: 'ok' }));
});

server.listen(PORT, () => {
  console.log(`Listening on port ${PORT}`);
});

The platform injects PORT (default 8080 in production). Your app must listen on process.env.PORT.

For TypeScript, add lang: typescript to the service config:

services:
  api:
    type: node
    lang: typescript
    path: /

This expects src/index.ts, tsconfig.json, and compiles via tsc before running.

Next.js

grid init app my-dashboard --type nextjs

cloudgrid.yaml:

name: my-dashboard
services:
  web:
    type: nextjs
    path: /
requires:
  - db
  - ai

next.config.mjs must set standalone output:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
};
export default nextConfig;

The platform builds Next.js using npm run build and runs the standalone server. No Dockerfile needed.

Build-time environment variables (e.g., NEXT_PUBLIC_*) go in the service’s build.env:

services:
  web:
    type: nextjs
    build:
      env:
        NEXT_PUBLIC_API_URL: "https://my-api.your-org.cloudgrid.io"

Python

grid init app my-service --type python

cloudgrid.yaml:

name: my-service
services:
  worker:
    type: python
    path: /
requires:
  - db

services/worker/src/main.py:

import os
from http.server import HTTPServer, BaseHTTPRequestHandler

PORT = int(os.environ.get('PORT', 8080))

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-Type', 'application/json')
        self.end_headers()
        self.wfile.write(b'{"status": "ok"}')

HTTPServer(('', PORT), Handler).serve_forever()

Dependencies go in services/worker/requirements.txt. The platform runs pip install -r requirements.txt during build.

Static Site

grid init app landing-page --type static

cloudgrid.yaml:

name: landing-page
services:
  site:
    type: static
    path: /

Place your index.html at services/site/index.html (the service root, not a public/ subdirectory). The platform serves it via nginx.

For a static site with a build step (Vite, Astro, etc.):

services:
  site:
    type: static
    path: /
    build:
      command: "npm run build"
      output: "dist"
      env:
        VITE_API_URL: "https://my-api.your-org.cloudgrid.io"
    node_version: "22"

The platform runs the build command and serves the output directory.