Pods are Doh's unified configuration system. Configuration uses the same hierarchical Resolution Order algorithm that governs dependency loading and pattern inheritance, ensuring consistent behavior across all systems.
The problems of application configuration—environment-specific overrides, type safety, inheritance patterns, and cross-component access—have been abstracted into a unified system that follows the same composition principles as other Doh components.
The configuration system provides:
The configuration system organizes settings through a file structure that separates concerns based on their lifecycle and purpose:
boot.pod.yaml: Application-wide settings that define module loading and core configuration. These are version-controlled, shared settings that establish the application's baseline behavior.
pod.yaml: Instance-specific override settings for developer and deployment customization. These are typically git-ignored, enabling local configuration without polluting the shared codebase.
Module Pods: Component-specific configuration encoded through Doh.Pod()
declarations, compiled into manifest data.
Package Pods: Structural configuration defined in .doh.yaml
files or Doh.Package()
definitions, encoding organizational settings into package metadata.
The configuration system uses the same Resolution Order algorithm that governs dependency loading and pattern inheritance, ensuring consistent behavior across all systems:
inherits:
- /path/to/base.pod.yaml
- https://example.com/shared.pod.yaml
- /pods/custom-config.pod.yaml
This allows for configuration composition where settings cascade from base configurations to more specific ones. The inheritance chain is resolved using the build_pod
function, which processes all inherited pods recursively.
Pod configuration embodies a deliberate security principle—separation between server and client namespaces to prevent accidental leakage of sensitive configuration to browsers:
Doh.pod: The complete pod configuration, including server-only settings like database credentials and API keys, available only in Node.js environments.
Doh.browser_pod: A curated subset of pod settings that are safe to expose to browser clients. The system automatically determines what can safely cross the client-server boundary.
This separation happens automatically—you configure once, and the system ensures sensitive data stays on the server while making appropriate settings available to client code.
Pods are integrated throughout the entire Doh ecosystem and automatically influence behavior across all systems:
Pods are compiled and cached before even the Auto-Packager runs, ensuring configuration is available for all subsequent operations:
// During server application startup (earliest phase)
await Doh.load_host_pod(args_pod, force_compile);
// During browser application startup
await Doh.load_browser_pod(args_pod);
The Auto-Packager automatically discovers and processes pod configurations from multiple sources:
.doh.yaml
files in all directories for package pod definitionsDoh.Pod()
calls in JavaScript files using AST analysisDoh.Pod()
callsThe Express router automatically uses pod settings for complete server configuration:
# All these settings come from Doh.pod.express_config
express_config:
port: 3000 # HTTP port binding
ssl_port: 443 # HTTPS port binding
hostname: 'localhost' # Server hostname
ssl_info: # SSL/TLS certificates
cert: '/path/to/cert.pem'
key: '/path/to/key.pem'
cors_hosts: [] # CORS allowed origins
rate_limit: # Rate limiting settings
windowMs: 900000
max: 100
host_forwards: # Host-based routing
'api.example.com': 'https://backend.local'
body_size_limit: '50mb' # Request body size limit
cache_max_age: 86400 # Static file cache headers
strict_hostnames: false # Hostname validation
log_routes: false # Route logging
Modules automatically receive pod-based configuration and support conditional loading:
Doh.Module('feature_module', [
// Conditional loading based on pod configuration
'Doh.pod.features.advanced?? advanced_features',
'Doh.pod.debug_mode?? debug_tools',
'browser&&Doh.pod.ui.enabled?? ui_components'
], function() {
// Access configuration directly
const config = Doh.pod.feature_module;
const isDebug = Doh.pod.debug_mode;
const serverConfig = Doh.pod.express_config;
});
Dohball deployment and hosting is entirely pod-driven:
# In pod.yaml
dohball_deployment:
expose_packages: '*' # Which packages to expose ('*' or array)
compile_manifest: true # Generate hosting manifest
rebake: false # Force rebuild all dohballs
worker_pool_size: 4 # Parallel build workers
ignore_packages: [] # Packages to exclude
ignore_paths: ['temp/', 'cache/'] # Paths to exclude
expose_doh_js: false # Whether to expose core Doh files
Browser pods are automatically compiled and served:
// Automatically generated and included in browser loads
Doh.browser_pod = {
// Only browser-safe configuration
api_endpoints: { ... },
ui_settings: { ... },
feature_flags: { ... }
// Server-only settings automatically excluded
};
Build processes use pod configuration:
Doh.Pod('esbuild_doh_plugin', {
esbuild_doh_plugin: {
deduplicate_packages: true,
replace_native_modules: true,
external_modules: ['fs', 'path'],
log_dedup_summary: false
}
});
Greenlock/Let's Encrypt configuration:
letsencrypt:
staging: false # Use production ACME server
force_renewal: false # Force certificate renewal
webroot: '/tmp/acme-challenge'
email: 'admin@example.com'
CLI behavior is pod-driven:
always_confirm_changes: true # Require confirmation for destructive operations
always_esbuild: false # Auto-run esbuild after changes
cleanup_orphaned_packages: true # Remove unused packages
packager_ignore: # Directories to skip during scanning
- 'temp/'
- 'cache/'
- 'logs/'
The Pod system uses Melded Object Composition (MOC) to provide type safety for configuration values. The moc
property in a pod defines type validation for its properties using a shallow-only approach:
moc:
apiUrl: 'IsString'
timeout: 'IsNumber'
retries: 'IsInt'
database: 'IsObject'
settings: 'IsObject'
# Note: Unlike Pattern MOC, nested structures like this are not supported:
# settings:
# debug: 'IsBoolean'
# logLevel: 'IsString'
This ensures that configuration values conform to expected types and can be validated at runtime. Pod MOC validation uses a shallow approach to support proper layering of configuration files.
The global object containing all pod settings merged from boot.pod.yaml, pod.yaml, and module pods. It is the primary way to access configuration values in server-side code:
const port = Doh.pod.express_config.port;
const apiKey = Doh.pod.api_keys.service_name;
const features = Doh.pod.my_module.features;
A subset of Doh.pod
that contains only browser-safe configuration values. This is made available to browser clients and excludes sensitive server-only configuration:
// In Node.js, both are available
console.log(Doh.pod.private_setting); // Available
console.log(Doh.browser_pod.api_endpoint); // Available
// In browser, only browser_pod settings are available
console.log(Doh.pod.api_endpoint); // Available in browser
console.log(Doh.pod.private_setting); // Undefined in browser
A function to define module-specific pod configuration:
Doh.Pod('my_module', {
moc: {
setting1: 'IsString',
setting2: 'IsNumber'
},
setting1: 'default value',
setting2: 100,
// Browser-safe settings
browser_pod: {
publicUrl: '/api/module'
}
});
These module pods are merged into the main pod configuration and follow the same inheritance rules.
When Doh starts, it processes pod files in a specific order:
/doh_js/default.pod.yaml
Doh.Pod()
definitions discovered by Auto-Packager.doh.yaml
files/boot.pod.yaml
/pod.yaml
[[Code:x:y]]:
snippets in pod definitions in a sandboxed, but pod aware Global scope.Doh.pod
and Doh.browser_pod
objects (Doh.browser_pod
is also mimic'ed to Doh.pod.browser_pod
so you can set it in pod files at the root level as browser_pod:
)This process ensures that local settings override application settings, which override defaults.
The host_load
property in pods defines which packages should be automatically loaded when the application starts:
host_load:
- express_router # Web server
- user_management # Authentication
- analytics # Tracking
- dohball_host # Package hosting
- storage_manager # File management
This provides a declarative way to define your application's entry points without needing to manually load modules in code.
The dohball_host
property defines which remote Doh instances should be used as sources for installing and upgrading remotely hosted Dohballs. This enables HTTP-based distribution of Dohballs without requiring Git. Note that this is ONLY for consuming code from external hosts - local code in your project is handled automatically by the Auto-Packager without any installation.
dohball_host:
- https://backup-host.com
- https://your-team-host.com
- http://localhost:3001
doh install
and doh upgrade
commands ONLY work with remote hosts configured heredoh install package_name
, Doh searches through the configured hosts in order.tar.gz
file directly via HTTPdoh upgrade
compares locally installed versions with remote host versions to determine updatesTo serve Dohballs via HTTP/S, configure a Doh instance as a host:
# In the hosting instance's pod.yaml
dohball_deployment:
compile_manifest: true
host_load:
- dohball_host # Enable the dohball_host module
# The hosting instance will serve baked Dohballs at:
# https://your-host.com/dohball/package_name
Dohballs support two complementary distribution approaches:
dohball_host
for real-time distribution without GitBoth methods can be used simultaneously, and consumers can mix and match based on their needs.
The Pod system uses several manifest files to optimize performance:
Doh.Pod()
callsThese files are automatically managed by the Doh runtime and can be cleared with CLI commands when needed.
Use pod inheritance for environment-specific settings:
# base.pod.yaml
express_config:
port: 3000
debug_mode: false
# development.pod.yaml
inherits:
- base.pod.yaml
express_config:
debug_mode: true
# production.pod.yaml
inherits:
- base.pod.yaml
express_config:
port: 80
ssl_port: 443
strict_hostnames: true
Pods support conditional loading based on configuration:
Doh.Module('feature_loader_module', [
'Doh.pod.features.advanced?? advanced_features',
'Doh.pod.debug_mode?? debug_tools',
'browser&&Doh.pod.ui.enabled?? ui_components'
], function() {
// Module implementation
});
Pods are automatically fingerprinted for cache invalidation:
// Automatically generated during compilation
pod.fingerprint = Doh.NewUUID(pod);
if (pod.browser_pod) {
pod.browser_pod.fingerprint = pod.fingerprint;
}
Pod MOC validation uses a shallow-only approach (unlike Pattern MOC) to support proper layering of configuration files. Each property's MOC definition will still meld recursively, but you cannot nest deep MOC structures with {}
in your outer layer:
Doh.Pod('config_with_validation', {
moc: {
// Shallow MOC definitions only
database_host: 'IsString',
database_port: 'IsNumber',
ssl_enabled: 'IsBoolean',
features: 'IsArray',
cache_ttl: 'IsNumber',
database: 'IsObject',
cache_settings: 'IsObject'
// This would NOT work in pods (but works in Patterns):
// database: {
// host: 'IsString', // Deep nesting not supported
// port: 'IsNumber'
// }
},
database_host: 'localhost',
database_port: 5432,
ssl_enabled: false,
features: ['analytics', 'caching'],
cache_ttl: 3600
});
This limitation exists because pods need to support stacking files as setting layers - when multiple pod files inherit and override each other, the MOC definitions must be able to merge cleanly without deep structural conflicts.
We're exploring ways to expand the MOC standard into the static space of the pod engine, potentially allowing more validation patterns while maintaining the layered configuration benefits.
For complex nested configurations, you can expose MOC directly in nested objects:
Doh.Pod('complex_config', {
moc: {
database: 'IsObject',
cache_settings: 'IsObject'
},
database: {
moc: {
host: 'IsString',
port: 'IsNumber',
ssl: 'IsBoolean'
},
host: 'localhost',
port: 5432,
ssl: false
},
cache_settings: {
moc: {
ttl: 'IsNumber',
max_size: 'IsNumber'
},
ttl: 3600,
max_size: 1000
}
});
This approach allows any layer in a nested pod object to define its own MOC, which will be melded with any other MOCs defined for the same key in other files, since pods are natively deep melded to represent a "static" settings perspective.
Doh provides a unified CLI system for managing pod configurations with array detection and consistent syntax:
# Show current value and inheritance chain
doh pod express_config.port
doh bootpod host_load
# Set values
doh pod express_config.port 3000
doh bootpod debug_mode true
# Add compile-time removal directives
doh pod ~~express_config.debug
doh bootpod ~~host_load
Arrays are detected via MOC metadata or existing values. The system provides consistent syntax:
# Add to arrays
doh pod inherits /path/to/pod.yaml
doh pod dohball_host https://host.com
doh bootpod host_load package1
# Mark for removal from arrays
doh pod inherits ~~path/to/pod.yaml
doh pod dohball_host ~~https://host.com
doh bootpod host_load ~~package1
The following commands are maintained for backward compatibility but route through the unified system:
# Add inheritance (routes to: doh pod inherits /path/to/pod.yaml)
doh inherits /path/to/pod.yaml
# Mark inheritance for removal (routes to: doh pod inherits ~~path/to/pod.yaml)
doh inherits ~~/path/to/pod.yaml
# Add packages to host_load (routes to: doh bootpod host_load package1 package2)
doh host_load package1 package2
# Mark packages for removal from host_load (routes to: doh bootpod host_load ~~package1 ~~package2)
doh host_load ~~package1 ~~package2
# Add host (routes to: doh pod dohball_host https://host.com)
doh dohball_host https://host.com
# Mark host for removal (routes to: doh pod dohball_host ~~https://host.com)
doh dohball_host ~~https://host.com
# Clear pod cache
doh clear-pod
# Clear all caches
doh clear-all
The unified pod system uses consistent syntax:
~~value
: Mark value for removal (both object keys and array items by name)~~setting
: Add compile-time removal directive (e.g., ~~debug_mode: true
)doh pod
edits /pod.yaml
, doh bootpod
edits /boot.pod.yaml
The pod_dashboard
module (if included in your application) provides a web interface for managing pod settings. It allows:
Access it at /admin/pods
in your application (with proper authentication).
Pods are integrated throughout the entire Doh ecosystem:
Pod validation leverages Doh's MOC system to support configuration layering:
moc:
# Basic Types
string_value: 'IsString'
number_value: 'IsNumber'
# Composite Types (shallow only)
config_enabled: 'IsBoolean'
config_level: 'IsInt'
config_name: 'IsStringAndHasValue'
# Advanced Validation
domains: ['IsArray', 'NotNull']
timeout: ['IsNumber', 'NotNull']
database: 'IsObject'
# Note: Deep nesting like this is not supported in pods:
# database:
# url: 'IsKeySafe'
# maxConnections: 'IsIntOrFalse'
# For nested validation, define MOC in the nested objects:
database:
moc:
url: 'IsKeySafe'
maxConnections: 'IsIntOrFalse'
url: 'postgresql://localhost:5432/mydb'
maxConnections: 10
This validation ensures configuration correctness and helps prevent runtime errors.
Separate Sensitive Data: Keep API keys, database credentials, and other sensitive information in separate pod files that are ignored in version control.
Use Browser_Pod Carefully: Only expose data to the browser that is truly necessary for client-side functionality.
Validate with MOC: Always define MOC validation rules for your configurations to catch errors early.
Structure Inheritance Wisely: Create logical layers of pod files:
Use Path References: For file paths in pod settings, use relative paths with DohPath()
in code to ensure cross-platform compatibility.
Leverage Conditional Loading: Use pod-based conditions to load features only when needed.
Cache Appropriately: Pods compile once per application start - design for this pattern.
Use Fingerprinting: Leverage automatic fingerprinting for cache invalidation in distributed systems.
inherits:
- /pods/app-defaults.pod.yaml
host_load:
- express_router
- user_routes
- api_service
- dashboard
app_version: '1.2.0'
app_name: 'My Doh Application'
express_config:
port: 3000
browser_pod:
api_base: '/api/v1'
app_name: 'My Doh Application'
inherits:
- /pods/localhost.pod.yaml
- /pods/dev-secrets.pod.yaml
express_config:
port: 4000 # Override the default port
debug_mode: true
dohball_deployment:
expose_packages: '*'
compile_manifest: true
Doh.Pod('user_module', {
moc: {
user_settings: {
max_sessions: 'IsInt',
default_role: 'IsString'
}
},
user_settings: {
max_sessions: 5,
default_role: 'user'
},
browser_pod: {
login_url: '/auth/login'
}
});
The Pod system ensures that configuration is consistent, type-safe, and available throughout your entire Doh application, from server-side modules to browser-side components, CLI tools, and infrastructure management.