Example: deploy a Marketplace app to a node
This article refers to SDK version v0.6.0. The current SDK version is N/A.
Overview
deploy_marketplace_node.py deploys a Marketplace application on a single node: it resolves the application by name, picks an app version (the latest published one by default, or a specific one by --version), and creates the workload with Compose Config/App Secrets seeded from that version's own published template.
Every service is deployed with the template's own defaults unless you override them. Overrides come from a .json file, or a .env-style file with one KEY=value per line, for ports and volumes (--compose-config-file), env vars (--app-secrets-file), or the workload's own App Config (--app-config-file/--app-config-id).
This script targets a single node. For the cluster-scope equivalent, with Deployment & Replicas and Placement Constraints on top, see Deploy Marketplace app (cluster).
Get the script
Download deploy_marketplace_node.py from the SDK's examples/ directory. If you haven't installed the SDK yet, see Getting started.
Set up credentials
The script reads the four Barbara API Credentials from environment variables, or from a .env file placed next to it (loaded automatically, or pointed at with --env-file). See Set up credentials in the Hello World walkthrough for the full picture.
Walk through the code
resolve_app_version() picks the version to deploy. With no --version, it asks the server for just the newest one instead of paging through everything itself:
versions = client.applications.list_versions(
application.id, size=1, sort_column="created", sort_order="desc"
)
With a --version name, it pages through with size/from_ until it finds a matching entry, since list_versions returns a single page (the server defaults to size=10), see client.applications.list_versions in the Reference.
The version's own template becomes the deployment's starting point:
compose_config, app_secrets = client.applications.default_services(app_version)
default_services(app_version) is a static method: it decodes the version's base64 template into the (compose_config, app_secrets) shape create_marketplace_workload expects, one entry per service, ready to deploy as-is or after overriding individual ports/volumes/env. Every service in the template must be echoed back on create, or the API rejects the whole request, so starting from default_services instead of building the shape by hand avoids that pitfall entirely.
An override file, given via --compose-config-file/--app-secrets-file, is merged into the template's defaults by service name: only the keys present in the file change, everything else keeps its default.
by_name = {item["name"]: item for item in base}
for override in overrides:
name = override["name"]
by_name[name][field] = {**by_name[name].get(field, {}), **override.get(field, {})}
A .env-style override file needs a #service_name section header per service for a multi-service app; a single-service app can omit it. See the script's module docstring for the exact .json and .env formats.
build_plan() assembles the deployment plan (resolved node, application, version, and services) before anything is sent, the same plan-then-apply shape used throughout this section: nothing is created until --apply is given.
Run it
# Read-only: print the deployment plan (resolved application/version, default services).
python deploy_marketplace_node.py my-node --app Grafana
# Deploy a specific version.
python deploy_marketplace_node.py my-node --app Grafana --version 10.3.3-b.7 --apply
# Override one service's ports/env before deploying.
python deploy_marketplace_node.py my-node --app Grafana --compose-config-file ports.json --apply
Try it
Run it without --apply first and check the resolved application_id/app_version_id, and the printed compose_config/app_secrets, match what Panel shows for that app's template. Pass an app name that doesn't exist, or a --version that isn't published, and read the resulting error. After deploying, run Node info & telemetry (or client.nodes.workloads.get_urls(...)) against the node to see the app's published URLs once it's running.
Extend it
- Deploy to several nodes. Wrap the
--applypath over a list of nodes, or resolve them from a group, instead of hardcoding a single target. - Replicate a live workload instead of the template. Look up an already-deployed workload's current services with
client.nodes.workloads.get_compose_config/get_app_secretsinstead of starting fromdefault_services, the same idea as Clone a node.
Summary
You resolved a Marketplace application and version by name, built its Compose Config/App Secrets from the version's own published template with default_services, and deployed the workload to a node, with a safe read-only plan by default.
Starting from the template's defaults, rather than reconstructing the shape by hand, avoids the length-mismatch errors a hand-built compose_config/app_secrets is prone to.
For the full deploy flow, including updating an already-deployed workload, see Marketplace workload deployment. For the full method list, see client.applications and client.nodes.workloads in the Reference.