Skip to content

Loading Hub content

Copy capabilities, task environments, and task sets from one Dreadnode platform into a self-hosted instance — including air-gapped installs.

A fresh self-hosted install starts with an empty Hub. You fill it by copying capabilities, task environments, and task sets from a platform that already has them — Dreadnode SaaS, or another on-prem instance.

Every copy runs from the dn CLI against the same OCI registry the platform uses internally — there is no separate export format or transfer service. A local folder is both the interchange between two connected platforms and the bundle you carry across an air gap.

The bulk sync verb takes two operands: one is a platform URL, the other a local directory. Which side is which decides the direction — you never pass a --pull / --push flag.

Terminal window
# Push a directory of capabilities up to a platform
$ dn capability sync ./stack https://platform.dreadnode.io
# Pull every capability in your org down into a directory
$ dn capability sync https://platform.dreadnode.io ./stack

A platform URL resolves to a profile you have already logged in to — see Authentication. If no logged-in profile matches the URL, the command stops and tells you to run dn login --server <url> first, so a push never silently goes nowhere. sync <dir> with no platform operand pushes to whatever --profile / --server you pass, so existing CI pipelines keep working unchanged.

If your workstation can reach both platforms, copy through a local staging folder. Log in to each platform once (dn login), then name them by URL:

  1. Pull from the source into a folder.

    Terminal window
    $ dn capability sync https://platform.dreadnode.io ./stack
    $ dn task sync https://platform.dreadnode.io ./stack
  2. Push the folder into your instance.

    Terminal window
    $ dn capability sync ./stack https://dreadnode.internal
    $ dn task sync ./stack https://dreadnode.internal

Each subfolder under ./stack is one artifact (./stack/<name>/), so the staging folder is inspectable, diffable, and safe to keep under version control.

The exact same folder is a portable bundle. The only difference is that the pull and the push happen on different machines, with the folder carried between them.

  1. On a connected machine, pull the content you want into a folder:

    Terminal window
    $ dn capability sync https://platform.dreadnode.io ./bundle
    $ dn task sync https://platform.dreadnode.io ./bundle
  2. Carry ./bundle into the network (removable media, approved transfer, etc.).

  3. On a machine that can reach the on-prem API, log in once and push it in:

    Terminal window
    $ dn login --server https://dreadnode.internal <key>
    $ dn capability sync ./bundle https://dreadnode.internal
    $ dn task sync ./bundle https://dreadnode.internal

The push machine only needs to reach your on-prem API — the on-prem instance itself never needs outbound access to the source platform.

A task set is a bookmark — a named list of task references — not a bundle, so by default only the manifest moves. To carry a set and the task environments it points at, use --with-members:

  1. Pull the set and its member environments into a bundle directory:

    Terminal window
    $ dn task-set pull acme/apex-web ./bundle --with-members --profile saas

    This writes ./bundle/task-set.yaml plus one subfolder per member task.

  2. Push the bundle. Members are published first, then the manifest, so it never references a task that isn’t on the target yet:

    Terminal window
    $ dn task-set push ./bundle --with-members --server https://dreadnode.internal --api-key <key>

If any member environment fails to publish, the manifest is not written — fix the failure and re-run rather than leaving a set with dangling references.

ContentCommandNotes
Capabilitiescapability sync <url> <dir> / sync <dir> <url>One subfolder per capability.
Task environmentstask sync <url> <dir> / sync <dir> <url>One subfolder per task; a single environment can also go to disk with task pull <ref> -o <dir>.
Task setstask-set pull <ref> <dir> --with-members / push <dir> --with-membersManifest + member environments; members ordered before the manifest on push.

Re-running any of these is safe: unchanged artifacts are skipped, so a folder can be topped up and re-pushed as the source platform gains new content.