Gluon

Deploy the app your template defines

Gluon is the control plane: register an application, attach a hostname, and run the same Leptos app on local Docker or a multi-cloud fleet. Boson workers and Photon nodes run on those targets.

Why this family exists

Gluon records applications, routes, HAProxy, DNS/ACME, and CI/CD against the same Valence models the rest of the stack uses.

Where it lands

Gluon turns the Leptos app into containers and provider targets so Boson jobs and Photon streams run on the same path as the UI.
Create an application with ApplicationService, bind a domain with attach_hostname, and let Chronon reconcile DNS and HAProxy. Agents (Parton) and heartbeats (Pion) cover remote nodes. Releases, git poll+build, and rolling upgrade live in gluon::cicd. The Gluon AWS study measures eight-cell status scans and eight-application Docker reconciliation on one control-plane host. Live EC2 reserve and DNS stay off that path. The remote-fleet template can enable this control plane alongside the UI. Fleet bootstrap composes Gluon with Nucleus when provisioning a cell.

In the workspace

Gluon turns the Leptos app into containers and provider targets so Boson jobs and Photon streams run on the same path as the UI.

Code sample

From the upstream getting-started docs — see also all code recipes on Resources.
Gluon app + domainGluon
Create an application and attach a hostname
use gluon::applications::{
    ApplicationService, ContainerConfigSpec, CreateApplicationParams, HealthCheckSpec,
};
use gluon::domain::attach_hostname;
use gluon::generated::{GluonApplicationAppKind, GluonDomainZone};

let app = ApplicationService::create(
    valence,
    CreateApplicationParams {
        name: "marketing".into(),
        image_ref: "ghcr.io/acme/marketing:latest".into(),
        app_kind: GluonApplicationAppKind::Service,
        container: ContainerConfigSpec {
            container_port: 8080,
            ..Default::default()
        },
        health_check: Some(HealthCheckSpec {
            endpoint: "/health".into(),
            ..Default::default()
        }),
        lb: None,
        route: None,
        desired_instances: 2,
        target_node_id: None,
        metadata_json: serde_json::json!({}),
    },
)
.await?;

let zone = GluonDomainZone::get("zone:example.com", valence)
    .await?
    .expect("zone");
attach_hostname(valence, &app, &zone, "app.example.com").await?;