page:recipes:member portal:next js:tenant workspaces

Host member portal with Next.js: tenant-scoped workspaces

Deploy a member portal built with Next.js on Ample using the multi-tenant relational data pattern. Compute runs the app in an isolated microVM behind a public HTTPS URL, a managed PostgreSQL 16 database is auto-provisioned and injected as DATABASE_URL. Verified on Next.js: a tenant column on every row and query, with a cross-tenant read returning nothing (tenant_isolation=ok). Not separately tested: your tenant model, membership and per-tenant authorization; treat the member portal-specific behavior as your application code.

Representative Queries

Resource Requirements

Infrastructure Requirements

  1. Compute
    • Status: verified
    • Summary: Apps run in isolated x86_64 Firecracker microVMs that auto-pause when idle and wake on request; sizes are the priced VM sizes.
  2. Postgres
    • Status: verified
    • Summary: Managed PostgreSQL 16 runs in its own microVM and is auto-provisioned when an app needs a database and no DATABASE_URL is supplied.

Framework

Next.js

Workload

Member portal

Release Status

Published

Support Status

Verified

Execution Status

Ready

Prerequisites

Tested Configuration

Workflow Steps

  1. Build and start
    next build then next start -H 0.0.0.0 -p $PORT on the node-22 template. The server must bind 0.0.0.0 on PORT.
  2. Implement the pattern on PostgreSQL
    The fixture's module implements multi-tenant relational data: a tenant column on every row and query, with a cross-tenant read returning nothing (tenant_isolation=ok). Copy the approach into your schema; keep migrations idempotent and run them with --release-command.
  3. Deploy
    Run the synchronous deploy once and read the result (exit 0 live, 1 failed, 2 blocked). Re-running with no change is a no-op. Command: ample deploy . --name --public
  4. Verify
    Fetch the live URL and the pattern self-test route(s) (/p/multi-tenant-relational-data) from the example; then run your own checks. On failure read ample logs --kind build then --kind runtime. Command: ample logs --kind build

Examples

Success Checks

Limitations

Cost Estimate

Evidence Summary

  1. Kind: canary_run

    • Summary: Next.js pattern fixture deployed on Ample (next build then next start -H 0.0.0.0 -p $PORT on the node-22 template); checks passed for multi-tenant-relational-data and configuration-secrets. Pattern proof: a tenant column on every row and query, with a cross-tenant read returning nothing (tenant_isolation=ok).
    • Observed At: 2026-09-21T02:34:39Z
    • Implementation Revision: 1d28ae0-dirty (CLI 0.1.21)
    • Expires At: 2027-03-20T02:34:39Z
  2. Kind: canary_run

    • Summary: The same Next.js app deployed with a --release-command migration; the marker it created was readable after activation.
    • Observed At: 2026-09-20T01:54:51Z
    • Implementation Revision: 199ff1dfd52683832ae75d3f98b53a7a4bff7f96-dirty (CLI e3181f5)
    • Expires At: 2027-03-19T01:54:51Z

Next Actions

  1. Label: Browse the catalog index
    • Operation Id: catalog_index
    • Method: GET
    • Relative Path: /v1/catalog
    • Requires Authentication: false
    • Requires Approval: false
  2. Label: Search published recipes by intent, stack and constraints
    • Operation Id: search_recipes
    • Method: POST
    • Relative Path: /v1/catalog/search
    • Parameters:
      • Body:
        • Limit: 5
        • Query: Host member portal with Next.js: tenant-scoped workspaces
    • Requires Authentication: false
    • Requires Approval: false
  3. Label: Prepare a side-effect-free deployment plan for an authorized project
    • Operation Id: plan_deployment
    • Method: POST
    • Relative Path: /v1/catalog/plan
    • Parameters:
      • Body:
        • Inputs: {}
        • Project ID: ""
        • Recipe ID: page:recipes:member-portal:next-js:tenant-workspaces
        • Recipe Revision: r1
    • Requires Authentication: true
    • Requires Approval: false
  4. Label: Read the existing agent authentication setup
    • Operation Id: existing_auth_setup
    • Method: GET
    • Relative Path: /mcp/setup
    • Requires Authentication: false
    • Requires Approval: false
  5. Label: Browse Member portal
    • Operation Id: browse_node
    • Method: GET
    • Relative Path: /v1/catalog/nodes/workload%3Amember-portal
    • Parameters:
      • Node ID: workload:member-portal
    • Requires Authentication: false
    • Requires Approval: false
  6. Label: Browse Next.js
    • Operation Id: browse_node
    • Method: GET
    • Relative Path: /v1/catalog/nodes/stack%3Aframework-next-js
    • Parameters:
      • Node ID: stack:framework-next-js
    • Requires Authentication: false
    • Requires Approval: false
  7. Label: Browse Multi-tenant relational data
    • Operation Id: browse_node
    • Method: GET
    • Relative Path: /v1/catalog/nodes/pattern%3Amulti-tenant-relational-data
    • Parameters:
      • Node ID: pattern:multi-tenant-relational-data
    • Requires Authentication: false
    • Requires Approval: false
  8. Label: Browse Deploy web app
    • Operation Id: browse_node
    • Method: GET
    • Relative Path: /v1/catalog/nodes/intent%3Adeploy-web-app
    • Parameters:
      • Node ID: intent:deploy-web-app
    • Requires Authentication: false
    • Requires Approval: false