# Docker Compose Platform Stack - Solo Mode # Imports configuration from user config files # User configs are located in ~/Library/Application Support/provisioning/platform/config/ (macOS) # or ~/.config/provisioning/platform/config/ (Linux) # NICKEL_IMPORT_PATH is set by platform-generate-manifests.nu using with-env # Usage: ./provisioning/scripts/platform-generate-manifests.nu docker let orchestrator_config = (import "orchestrator.ncl").orchestrator in let control_center_config = (import "control-center.ncl").control_center in let mcp_server_config = (import "mcp-server.ncl").mcp_server in { services = { # External Infrastructure Services (required for platform to function) # SurrealDB: Database for orchestrator and control-center # Solo mode uses in-memory storage (memory) for simplicity # Change to rocksdb:/data for persistent storage surrealdb = { image = "surrealdb/surrealdb:latest", container_name = "surrealdb-solo", command = "start --log=warn --bind 0.0.0.0:8000 memory", ports = [ "8000:8000", ], networks = ["provisioning-net"], restart = "unless-stopped", healthcheck = { test = ["CMD", "curl", "-f", "http://localhost:8000/health"], interval = "10s", timeout = "5s", retries = 3, start_period = "10s", }, }, # Zot: OCI registry for extension distribution # Optional: Can be disabled if extensions are loaded from filesystem zot = { image = "ghcr.io/project-zot/zot:latest", container_name = "zot-solo", ports = [ "5000:5000", ], environment = { ZOT_LOG_LEVEL = "info", }, volumes = [ "zot_data:/var/lib/registry", ], networks = ["provisioning-net"], restart = "unless-stopped", healthcheck = { test = ["CMD", "curl", "-f", "http://localhost:5000/v2/"], interval = "10s", timeout = "5s", retries = 3, start_period = "10s", }, }, # Forgejo: Git source for extension discovery and releases # Optional: Can use external Forgejo/Gitea instance instead forgejo = { image = "codeberg.org/forgejo/forgejo:latest", container_name = "forgejo-solo", ports = [ "3000:3000", "2222:22", ], environment = { USER_UID = "1000", USER_GID = "1000", FORGEJO_SECURITY_SECRET_KEY = "changeme_in_production", FORGEJO_SECURITY_INSTALL_LOCK = "true", }, volumes = [ "forgejo_data:/data", ], networks = ["provisioning-net"], restart = "unless-stopped", healthcheck = { test = ["CMD", "curl", "-f", "http://localhost:3000/api/v1/version"], interval = "10s", timeout = "5s", retries = 3, start_period = "30s", }, }, # Platform Services (internal) orchestrator = { build = { context = ".", dockerfile = "crates/orchestrator/Dockerfile", }, container_name = "orchestrator", ports = [ (std.string.from_number orchestrator_config.server.port) ++ ":8080", ], environment = { ORCHESTRATOR_MODE = "solo", ORCHESTRATOR_SERVER_HOST = orchestrator_config.server.host, ORCHESTRATOR_SERVER_PORT = "8080", ORCHESTRATOR_STORAGE_BACKEND = orchestrator_config.storage.backend, ORCHESTRATOR_STORAGE_PATH = orchestrator_config.storage.path, RUST_LOG = "info", }, volumes = [ "orchestrator_data:/data", "orchestrator_logs:/var/log/orchestrator", ], networks = ["provisioning-net"], restart = "unless-stopped", healthcheck = { test = ["CMD", "curl", "-f", "http://localhost:8080/health"], interval = "10s", timeout = "5s", retries = 3, start_period = "10s", }, }, control-center = { build = { context = ".", dockerfile = "crates/control-center/Dockerfile", }, container_name = "control-center", ports = [ (std.string.from_number control_center_config.server.port) ++ ":8081", ], environment = { CONTROL_CENTER_MODE = "solo", CONTROL_CENTER_SERVER_HOST = control_center_config.server.host, CONTROL_CENTER_SERVER_PORT = "8081", CONTROL_CENTER_DATABASE = control_center_config.database.backend, CONTROL_CENTER_DATABASE_PATH = control_center_config.database.path, ORCHESTRATOR_URL = "http://orchestrator:8080", RUST_LOG = "info", }, volumes = [ "control_center_data:/data", ], networks = ["provisioning-net"], restart = "unless-stopped", depends_on = { orchestrator = { condition = "service_healthy", }, }, healthcheck = { test = ["CMD", "curl", "-f", "http://localhost:8081/health"], interval = "10s", timeout = "5s", retries = 3, start_period = "10s", }, }, mcp-server = { build = { context = ".", dockerfile = "crates/mcp-server/Dockerfile", }, container_name = "mcp-server", ports = [ (std.string.from_number mcp_server_config.server.port) ++ ":8082", ], environment = { MCP_SERVER_MODE = "solo", MCP_SERVER_HOST = mcp_server_config.server.host, MCP_SERVER_PORT = "8082", MCP_SERVER_PROTOCOL = "stdio", ORCHESTRATOR_URL = "http://orchestrator:8080", RUST_LOG = "info", }, volumes = [ "mcp_server_data:/data", ], networks = ["provisioning-net"], restart = "unless-stopped", depends_on = { orchestrator = { condition = "service_healthy", }, }, healthcheck = { test = ["CMD", "curl", "-f", "http://localhost:8082/health"], interval = "10s", timeout = "5s", retries = 3, start_period = "10s", }, }, provisioning-daemon = { build = { context = ".", dockerfile = "crates/provisioning-daemon/Dockerfile", }, container_name = "provisioning-daemon", ports = [ "8079:8079", ], environment = { RUST_LOG = "info", DATA_DIR = "/data", PROVISIONING_DAEMON_MODE = "solo", PROVISIONING_CONFIG_DIR = "/etc/provisioning", }, volumes = [ "daemon_data:/data", "daemon_config:/etc/provisioning", ], networks = ["provisioning-net"], restart = "unless-stopped", depends_on = { orchestrator = { condition = "service_healthy", }, }, healthcheck = { test = ["CMD", "curl", "-f", "http://localhost:8079/api/v1/health"], interval = "30s", timeout = "10s", retries = 3, start_period = "30s", }, }, # TODO: provisioning-rag requires stratum-llm and stratum-embeddings workspace resolution # Disabled temporarily until workspace dependencies are resolved # provisioning-rag = { ... }, }, volumes = { # External services volumes zot_data = null, forgejo_data = null, # Platform services volumes orchestrator_data = null, orchestrator_logs = null, control_center_data = null, mcp_server_data = null, daemon_data = null, daemon_config = null, }, networks = { provisioning-net = { driver = "bridge", }, }, }