The generators module provides functions to create all supporting files for a complete OpenClaw stack deployment: environment files, shell scripts, proxy configs, monitoring dashboards, and more.
Overview
Generators transform a ResolverOutput into specific file content. The main generate() function orchestrates all generators, but you can use individual generators directly.
import {
generateEnvFiles,
generateCaddyfile,
generateScripts,
generateReadme
} from '@better-openclaw/core';
Environment Files
generateEnvFiles
Generates .env.example and .env files with all required environment variables.
import { generateEnvFiles } from '@better-openclaw/core';
import type { EnvGeneratorOptions } from '@better-openclaw/core';
const { envExample, env } = generateEnvFiles(resolved, {
generateSecrets: true,
domain: 'example.com',
openclawVersion: 'latest',
composeFiles: ['docker-compose.yml', 'docker-compose.ai.yml'],
composeProfiles: ['ai', 'media']
});
await writeFile('.env.example', envExample);
await writeFile('.env', env);
Resolved service configuration
options
EnvGeneratorOptions
required
Generation options
Auto-generate cryptographically random secrets
Compose file names for COMPOSE_FILE env var
Profile names for COMPOSE_PROFILES env var
Service IDs running natively on host (for bare-metal)
Image variant (“official”, “coolify”, “alpine”)
Returns: { envExample: string, env: string }
getStructuredEnvVars
Returns structured environment variables grouped by service.
import { getStructuredEnvVars } from '@better-openclaw/core';
import type { EnvVarGroup } from '@better-openclaw/core';
const groups: EnvVarGroup[] = getStructuredEnvVars(resolved, options);
groups.forEach(group => {
console.log(`${group.serviceName}:`);
group.variables.forEach(v => {
console.log(` ${v.key}=${v.value}`);
});
});
Returns: Array of EnvVarGroup objects with serviceName and variables array.
Reverse Proxy Configs
generateCaddyfile
Generates a complete Caddyfile with reverse proxy routes for all services.
import { generateCaddyfile } from '@better-openclaw/core';
const caddyfile = generateCaddyfile(resolved, 'example.com');
await writeFile('caddy/Caddyfile', caddyfile);
Main domain (e.g., “example.com”)
Returns: Caddyfile content as string
Generated routes:
service-id.example.com → service primary port
service-id-alt.example.com → additional exposed ports
example.com → OpenClaw gateway
generateTraefikConfig
Generates Traefik static config and dynamic service labels.
import { generateTraefikConfig } from '@better-openclaw/core';
// Called automatically by compose() when proxy: 'traefik'
const { staticConfig, serviceLabels } = generateTraefikConfig(resolved, 'example.com');
await writeFile('traefik/traefik.yml', staticConfig);
// serviceLabels are injected into docker-compose service definitions
Note: Traefik labels are automatically added to services via the composer. You typically don’t call this directly.
Shell Scripts
generateScripts
Generates helper shell scripts for managing the stack.
import { generateScripts } from '@better-openclaw/core';
const scripts = generateScripts();
for (const [path, content] of Object.entries(scripts)) {
await writeFile(path, content, { mode: 0o755 });
}
Returns: Record<string, string> with these files:
scripts/start.sh - Start all services (validates prereqs, generates secrets)
scripts/stop.sh - Stop all services gracefully
scripts/restart.sh - Restart all services
scripts/logs.sh - View service logs
scripts/backup.sh - Backup volumes and configs
scripts/restore.sh - Restore from backup
scripts/update.sh - Pull latest images and restart
generateHealthCheck
Generates stack-specific health check scripts.
import { generateHealthCheck } from '@better-openclaw/core';
const healthCheckFiles = generateHealthCheck(resolved, {
projectName: 'my-stack',
deploymentType: 'docker'
});
for (const [path, content] of Object.entries(healthCheckFiles)) {
await writeFile(path, content, { mode: 0o755 });
}
Returns: Record<string, string> with:
scripts/health-check.sh - Comprehensive health check for all services
scripts/health-check.ps1 - Windows PowerShell version
PostgreSQL
generatePostgresInit
Generates a database initialization script for services that need dedicated PostgreSQL databases.
import { generatePostgresInit } from '@better-openclaw/core';
const initScript = generatePostgresInit(resolved);
if (initScript) {
await writeFile('postgres/init-databases.sh', initScript, { mode: 0o755 });
}
Returns: Shell script content or null if no PostgreSQL
What it does:
- Creates database users for each service
- Creates dedicated databases
- Grants privileges
- Idempotent (safe to run multiple times)
getDbRequirements
Returns which services need dedicated PostgreSQL databases.
import { getDbRequirements } from '@better-openclaw/core';
const dbReqs = getDbRequirements(resolved);
dbReqs.forEach(req => {
console.log(`${req.serviceId} needs DB: ${req.dbName}`);
console.log(` User: ${req.dbUser}`);
console.log(` Password env: ${req.passwordEnvVar}`);
});
Returns: Array of { serviceId, dbName, dbUser, passwordEnvVar }
Monitoring
generatePrometheusConfig
Generates Prometheus configuration with service discovery.
import { generatePrometheusConfig } from '@better-openclaw/core';
const hasPrometheus = resolved.services.some(s => s.definition.id === 'prometheus');
if (hasPrometheus) {
const config = generatePrometheusConfig(resolved);
await writeFile('prometheus/prometheus.yml', config);
}
Returns: prometheus.yml content with scrape configs for all services
generateGrafanaConfig
Generates Grafana datasource and provisioning configs.
import { generateGrafanaConfig } from '@better-openclaw/core';
const hasGrafana = resolved.services.some(s => s.definition.id === 'grafana');
if (hasGrafana) {
const grafanaFiles = generateGrafanaConfig();
for (const [path, content] of Object.entries(grafanaFiles)) {
await writeFile(path, content);
}
}
Returns: Record<string, string> with:
config/grafana/datasources/prometheus.yml
config/grafana/dashboards/dashboard.yml
generateGrafanaDashboard
Generates a pre-configured OpenClaw stack overview dashboard.
import { generateGrafanaDashboard } from '@better-openclaw/core';
const dashboard = generateGrafanaDashboard();
await writeFile('config/grafana/dashboards/openclaw-stack-overview.json', dashboard);
Returns: Grafana dashboard JSON
Workflow Automation
generateN8nWorkflows
Generates starter n8n workflows for common automation tasks.
import { generateN8nWorkflows } from '@better-openclaw/core';
const n8nWorkflows = generateN8nWorkflows(resolved);
for (const [path, content] of Object.entries(n8nWorkflows)) {
await writeFile(path, content);
}
Returns: Record<string, string> with workflow JSON files in n8n/workflows/
Skills
generateSkillFiles
Generates OpenClaw skill configuration files.
import { generateSkillFiles } from '@better-openclaw/core';
const skillFiles = generateSkillFiles(resolved);
for (const [path, content] of Object.entries(skillFiles)) {
await writeFile(path, content);
}
Returns: Record<string, string> with skill manifest files
Documentation
generateReadme
Generates a comprehensive README.md for the stack.
import { generateReadme } from '@better-openclaw/core';
const readme = generateReadme(resolved, {
projectName: 'my-stack',
domain: 'example.com',
proxy: 'caddy',
deploymentType: 'docker',
hasNativeServices: false,
openclawInstallMethod: 'docker'
});
await writeFile('README.md', readme);
options.hasNativeServices
Whether native services are included
options.openclawInstallMethod
OpenClaw install method
Returns: Complete README.md content with:
- Quick start instructions
- Service list with URLs
- Configuration guide
- Troubleshooting tips
generateStackManifest
Generates a machine-readable stack manifest for Mission Control.
import { generateStackManifest } from '@better-openclaw/core';
import type { StackManifest } from '@better-openclaw/core';
const manifestFiles = generateStackManifest(resolved, input);
for (const [path, content] of Object.entries(manifestFiles)) {
await writeFile(path, content);
}
Returns: Record<string, string> with stack-manifest.json
generateCloudInit
Generates a cloud-init configuration for automated VPS deployment.
import { generateCloudInit } from '@better-openclaw/core';
const cloudInit = generateCloudInit({
composeYaml: composeResult.files['docker-compose.yml'],
envContent: envFiles.env,
projectName: 'my-stack',
gatewayPort: 18789
});
await writeFile('cloud-init.yml', cloudInit);
Returns: cloud-init YAML for VPS provisioning
Generates bare-metal installation scripts.
import { generateBareMetalInstall } from '@better-openclaw/core';
const bareMetalFiles = generateBareMetalInstall({
platform: 'linux/amd64',
projectName: 'my-stack',
hasNativeServices: true
});
for (const [path, content] of Object.entries(bareMetalFiles)) {
await writeFile(path, content);
}
generateNativeInstallScripts
Generates native service install scripts for bare-metal deployments.
import { generateNativeInstallScripts } from '@better-openclaw/core';
const nativeScripts = generateNativeInstallScripts({
nativeServices: partition.nativeServices,
platform: 'linux',
projectName: 'my-stack'
});
for (const [path, content] of Object.entries(nativeScripts)) {
await writeFile(path, content, { mode: 0o755 });
}
Main Orchestrator
generate
Orchestrates all generators to create a complete stack.
import { generate } from '@better-openclaw/core';
import type { GenerationInput, GenerationResult } from '@better-openclaw/core';
const result: GenerationResult = generate({
projectName: 'my-stack',
services: ['redis', 'postgresql', 'n8n'],
skillPacks: ['ai-toolkit'],
proxy: 'caddy',
domain: 'example.com',
platform: 'linux/amd64',
deploymentType: 'docker',
deployment: 'local',
generateSecrets: true,
monitoring: true
});
console.log('Generated files:', Object.keys(result.files).length);
console.log('Service count:', result.metadata.serviceCount);
console.log('Skill count:', result.metadata.skillCount);
console.log('Memory estimate:', result.metadata.estimatedMemoryMB, 'MB');
// Write all files
for (const [path, content] of Object.entries(result.files)) {
await writeFile(path, content);
}
See Generation API for complete details.
Types
EnvVarGroup
interface EnvVarGroup {
serviceName: string;
serviceId: string;
variables: Array<{
key: string;
value: string;
secret: boolean;
description: string;
}>;
}
StackManifest
interface StackManifest {
version: string;
projectName: string;
services: StackManifestService[];
skills: StackManifestSkill[];
generated: string;
}
Examples
Custom Environment Generation
import { getStructuredEnvVars } from '@better-openclaw/core';
const groups = getStructuredEnvVars(resolved, {
generateSecrets: true,
domain: 'example.com'
});
// Filter only secrets
const secrets = groups.flatMap(g =>
g.variables.filter(v => v.secret)
);
console.log('Secrets to configure:');
secrets.forEach(s => {
console.log(` ${s.key}: ${s.description}`);
});
Selective File Generation
import {
generateEnvFiles,
generateScripts,
generateReadme,
generateCaddyfile
} from '@better-openclaw/core';
// Only generate what you need
const files: Record<string, string> = {};
const { env, envExample } = generateEnvFiles(resolved, options);
files['.env'] = env;
files['.env.example'] = envExample;
const scripts = generateScripts();
Object.assign(files, scripts);
const readme = generateReadme(resolved, readmeOptions);
files['README.md'] = readme;
if (input.proxy === 'caddy') {
files['caddy/Caddyfile'] = generateCaddyfile(resolved, input.domain!);
}
See Also