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.
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_dropandsecurity_opt - Replace
depends_onreferences 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:
- Input validation — the input is parsed against
AddonStackInputSchema(a Zod schema). Invalid input fails fast with clear error messages. - Infrastructure filtering — service IDs like
redis,postgresql,caddy, andopenclaw-gatewayare automatically removed. A warning is added so you can inform the user. - Dependency resolution — the resolver expands dependencies (e.g., n8n needs PostgreSQL setup) and performs topological sorting to ensure correct startup order.
- Credential checking — services requiring external API keys (like OpenAI or Anthropic) are flagged as "skipped" with the reason
missing_credentialsif the user hasn't provided them. - Compose generation — each service gets a Docker Compose entry with image, volumes, environment, healthcheck, and network configuration. No
profiles:, nocap_drop:— clean output. - Port conflict resolution — if a service's default port conflicts with your
reservedPorts, it's automatically reassigned to port+1000. - 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
envQuirkssystem. - 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
envFilecontains 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-networkas 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.