Back to Blog
TutorialsMarch 12, 202614 min read

How Hosting Providers Can Offer 180+ Self-Hosted Services with One API Call

A practical guide to integrating @better-openclaw/core's addon stack generation into your hosting platform. Generate Docker Compose overlays, manage secrets, resolve port conflicts, and offer a full service marketplace — all without post-processing hacks.

addon-stackhostingdocker-composeintegrationopenclawapimarketplace

If you run a hosting platform and want to offer your users the ability to install self-hosted services like n8n, Qdrant, Meilisearch, Grafana, or any of the 180+ services in the OpenClaw catalog — this guide is for you. The new Addon Stack API in @better-openclaw/core lets you generate production-ready Docker Compose overlays with a single function call.

No more post-processing YAML. No more manually filtering infrastructure services. No more hand-rolling secret generation. The addon stack API does it all.

The Problem: Full-Stack Generation Doesn't Fit Hosting Providers

OpenClaw's existing generate() function creates complete standalone stacks — it includes everything from the reverse proxy (Caddy/Traefik) to Redis, PostgreSQL, and the OpenClaw gateway. That's perfect for someone setting up a fresh server, but hosting providers like Clawexa already have that infrastructure provisioned via cloud-init.

Until now, integrators had to call generate() and then apply a series of fragile post-processing steps:

  • Strip out infrastructure services (redis, postgresql, caddy, etc.)
  • Remove profiles: from individual services
  • Remove cap_drop and security_opt
  • Replace depends_on references to removed services
  • Filter environment variables that clash with existing infrastructure
  • Generate secrets separately
  • Resolve port conflicts with existing services

That's 18+ hacks in production code. Each one is a maintenance burden and a source of bugs when the core library updates.

The Solution: First-Class Addon Stack Generation

The new generateAddonStack() function produces only the addon layer — the services your users actually requested, with all infrastructure concerns handled internally.

import { generateAddonStack } from "@better-openclaw/core";

const result = generateAddonStack({
  instanceId: "user-abc-123",
  services: ["n8n", "qdrant", "meilisearch"],
  generateSecrets: true,
  reservedPorts: [3000, 5432, 6379, 8080],
});

// result.composeOverride  → ready-to-write docker-compose.override.yml
// result.envFile          → .env with generated secrets
// result.proxyRoutes      → [{serviceId:"n8n", path:"/n8n", port:5678, ...}]
// result.skillFiles       → skill definitions for the OpenClaw gateway
// result.warnings         → any non-fatal issues

That's it. One function call, zero post-processing.

What Happens Under the Hood

When you call generateAddonStack(), the function runs a carefully-ordered pipeline:

  1. Input validation — the input is parsed against AddonStackInputSchema (a Zod schema). Invalid input fails fast with clear error messages.
  2. Infrastructure filtering — service IDs like redis, postgresql, caddy, and openclaw-gateway are automatically removed. A warning is added so you can inform the user.
  3. Dependency resolution — the resolver expands dependencies (e.g., n8n needs PostgreSQL setup) and performs topological sorting to ensure correct startup order.
  4. Credential checking — services requiring external API keys (like OpenAI or Anthropic) are flagged as "skipped" with the reason missing_credentials if the user hasn't provided them.
  5. Compose generation — each service gets a Docker Compose entry with image, volumes, environment, healthcheck, and network configuration. No profiles:, no cap_drop: — clean output.
  6. Port conflict resolution — if a service's default port conflicts with your reservedPorts, it's automatically reassigned to port+1000.
  7. Secret generation — random 48-character hex secrets for all passwords and API keys. Services with special requirements (like Convex needing 64-character secrets) are handled via the envQuirks system.
  8. Proxy route extraction — services with a proxyPath (like /n8n) generate structured proxy routes you can feed to Caddy, Traefik, or nginx.

Handling Service Updates Without Downtime

Users don't just install services once — they add and remove them over time. The updateAddonStack() function handles incremental changes:

import { updateAddonStack } from "@better-openclaw/core";

const result = updateAddonStack({
  instanceId: "user-abc-123",
  currentCompose: existingYaml,
  currentEnv: existingEnvFile,
  addServices: ["grafana"],
  removeServices: ["meilisearch"],
  generateSecrets: true,
});

// result.metadata.added     → ["grafana"]
// result.metadata.removed   → ["meilisearch"]
// result.metadata.unchanged → ["n8n", "qdrant"]
// result.imagesToPull       → ["grafana/grafana:latest"]
// result.envFile            → existing values PRESERVED, new ones added

The key feature here is env preservation. If a user has customized their Qdrant API key or n8n webhook URL, those values are kept intact. Only new services get fresh secrets.

Real-World Integration: A Complete Provisioning Flow

Here's how a hosting platform's provisioning engine would use both functions together:

// 1. User selects services from your marketplace UI
const selectedServices = ["n8n", "qdrant", "meilisearch"];

// 2. Generate the initial addon stack
const stack = generateAddonStack({
  instanceId: `tenant-${tenantId}`,
  services: selectedServices,
  reservedPorts: getInfrastructurePorts(),
  generateSecrets: true,
});

// 3. Handle skipped services
for (const skipped of stack.metadata.skippedServices) {
  switch (skipped.reason) {
    case "missing_credentials":
      // Show credential input form in your UI
      await showCredentialPrompt(skipped);
      break;
    case "gpu_required":
      // Suggest GPU plan upgrade
      await showUpgradePrompt(skipped.serviceId);
      break;
  }
}

// 4. Write compose overlay and env file to the instance
await fs.writeFile(
  `/instances/${tenantId}/docker-compose.override.yml`,
  stack.composeOverride
);
await fs.writeFile(
  `/instances/${tenantId}/.env.addons`,
  stack.envFile
);

// 5. Write skill definitions
for (const [filename, content] of Object.entries(stack.skillFiles)) {
  await fs.writeFile(
    `/instances/${tenantId}/config/skills/${filename}`,
    content
  );
}

// 6. Register proxy routes with Caddy/Traefik
for (const route of stack.proxyRoutes) {
  await reverseProxy.addRoute({
    path: route.path,
    upstream: `${route.serviceId}:${route.port}`,
    stripPrefix: route.stripPrefix,
  });
}

// 7. Start the containers
await docker.composeUp(`/instances/${tenantId}`);

The Service Catalog: Building Your Marketplace

The @better-openclaw/core package exports the full service registry. Use it to build your marketplace UI:

import {
  getAllServices,
  getServicesByCategory,
  SERVICE_CATEGORIES,
} from "@better-openclaw/core";

// 180+ services across 30+ categories
const allServices = getAllServices();

// Categories include:
// AI Platforms, Automation, Vector DBs, Monitoring,
// Search, Knowledge Management, Browser Automation, etc.

for (const category of SERVICE_CATEGORIES) {
  const services = getServicesByCategory(category.id);
  console.log(`${category.icon} ${category.name} (${services.length})`);
  for (const svc of services) {
    console.log(`  - ${svc.name}: ${svc.description}`);
    console.log(`    RAM: ~${svc.memoryMB}MB | Maturity: ${svc.maturity}`);
  }
}

Each service definition includes everything your marketplace needs: name, description, icon, category, estimated memory usage, maturity level, required environment variables (with descriptions), and exposed ports.

Security Considerations

When integrating the addon stack API into a multi-tenant hosting platform, keep these security practices in mind:

  • Validate all input with AddonStackInputSchema.parse() before passing to the generator. Never trust user-provided service IDs without validation.
  • Store secrets securely — the generated envFile contains passwords and API keys. Encrypt at rest and restrict access.
  • Use reserved ports aggressively — pass every port your infrastructure uses. This prevents addon services from binding to ports needed by your control plane.
  • Review skipped services — never deploy a service that was skipped due to missing_credentials. The service would start in a broken state.
  • Network segmentation — the generated compose uses openclaw-network as an external network. In multi-tenant environments, create per-tenant networks for isolation.

What's Next

The addon stack API is the foundation for a new generation of OpenClaw hosting integrations. Coming soon:

  • Managed upgrades — automated service version bumps with rollback support
  • Resource quotas — per-tenant memory and CPU limits integrated into the compose output
  • Backup integration — automated volume backup schedules generated alongside the stack

Ready to integrate? Check out the Addon Stack API Reference and the Hosting Provider Integration Guide for complete documentation.

Skip the infrastructure setup? Deploy your stack on Better-Openclaw Cloud — the hosted version of better-openclaw.

SYSTEM_AUDIT_PROTOCOL_V4

VALIDATION CONSOLE

Live system audit interface verifying production readiness, compliance, and operational integrity for better-openclaw deployments.

PRODUCTION ENVIRONMENT ACTIVE

ENTERPRISE

INTEGRITY

System infrastructure verified for high-availability environments. Zero-trust architecture enforced across all active nodes.

COMPLIANCE_LOGID: 8842-XC
SOC2 Type II[VERIFIED]
ISO 27001[ACTIVE]
GDPR / CCPA[COMPLIANT]
SECURITY_PROTOCOL

AES-256

End-to-end encryption active for data at rest and in transit.

READY TO LAUNCH

SYSTEM READY

  • 1Create workspace (30s)
  • 2Connect repo & deploy agent
  • 3Monitor nodes in real-time
🦞 better-openclaw
SYSTEM_STATUSOPERATIONALv1.2.0

SET_STARTED

START BUILDING

Initialize your instance and deploy your first agent in seconds.

GET API KEY →

© 2026 AXION INC. REIMAGINED FOR BETTER-OPENCLAW

ALL SYSTEMS NORMALMADE IN BIDEW