Skip to content

Containers

Terminal window
swarm container deploy --repo <git-url> [--ref branch] [--vm my-server] [--alias dev] [--count N]
Flag Default behavior
--repo Required. Git repository URL to clone.
--ref Branch, tag, or commit. Defaults to the repo’s default branch.
--vm Auto-selects the only registered VM. Required when multiple VMs exist. Accepts name or UUID. Cannot be used with --count.
--alias Optional. Gives the container a short name for use in other commands.
--count Deploy multiple containers in one command (1–100). Uses auto-placement across VMs. Default: 1.
--env Environment variable for the container, KEY=VALUE. Repeatable. Values are stored server-side and never returned by the API.
--env-file Path to a KEY=VALUE env file for the container. Repeatable; blank lines and # comments are ignored. --env wins on key conflicts.
--secret Name of a secret from the server’s secret store to inject. Repeatable. Inline --env wins on key conflicts.

On first deploy to a VM, the server automatically bootstraps it (installs Docker, Node.js, the devcontainer CLI, and the swarm-agent). Subsequent deploys to the same VM skip bootstrapping.

Private repos work out of the box when the server has git_credentials configured for the host — the token is injected at clone time and never stored in the registry:

"git_credentials": [{ "host": "github.com", "token": "<fine-grained-token>" }]

Use a read-only, repo-scoped token; it travels to the agent over the SSH tunnel on each deploy. Repos without a matching credential (e.g. scp-style SSH URLs) are cloned unauthenticated.

Credentials can also be registered from the CLI instead of editing the server config — the token is read from stdin so it never lands in shell history:

Terminal window
swarm git-credential add github.com # paste token, then Enter
swarm git-credential list
swarm git-credential remove github.com

Client-registered credentials are stored in a root-only file next to the registry and take precedence over the config on host conflicts.

Containers often need env vars at start time (post-create scripts, runtime config). Swarm stores them server-side and injects them via devcontainer up --remote-env — values never appear in container list/info responses (key names only) and are redacted from agent output.

Inline env, from flags or a local file:

Terminal window
swarm container deploy --repo <git-url> --env NMUX_GEMFURY_TOKEN=... \
--env-file secrets.env --alias dev

For values you want to rotate without touching every deploy, register a named secret (value is read from stdin, so it never lands in shell history). The secret name is injected verbatim as the environment variable key — name it exactly what the container should see (names must be valid env var names: [A-Za-z_][A-Za-z0-9_]*):

Terminal window
swarm secret set NMUX_GEMFURY_TOKEN # paste value, then Enter
swarm secret list # names only, never values
swarm secret remove NMUX_GEMFURY_TOKEN
swarm container deploy --repo <git-url> --secret NMUX_GEMFURY_TOKEN --alias dev

Named secrets live in a root-only file (secrets.json) next to the registry. At deploy time the server resolves names to values and merges them with inline --env, with inline env winning on key conflicts. A deploy referencing an unknown secret is rejected immediately. Secrets inject at container start time; anything a Dockerfile needs during the image build is a Dockerfile concern (use BuildKit RUN --mount=type=secret there — build args are baked into image history).

Deploy multiple containers of the same repo in one command:

Terminal window
swarm container deploy --repo https://github.com/example/project --alias dev --count 5

Batch deploy uses least-loaded placement — each container is assigned to the VM with the fewest existing containers. Containers are deployed in parallel across VMs (one SSH connection per VM, sequential within each VM).

When --count is greater than 1, aliases get numeric suffixes: dev-1, dev-2, dev-3, etc. With --count 1, the alias is used verbatim.

Batch deploy handles partial failures — if one VM is unreachable or a container fails to create, the remaining containers still deploy. Failed containers are reported in the output with their error.

--vm cannot be used with --count; batch deploy always uses auto-placement.

Terminal window
swarm container list

Output:

ID VM ALIAS STATUS CONTAINER ID
a1b2c3d4e5f67890 my-server dev running docker-abc123

The server queries each VM’s agent for live Docker status before returning results.

Possible status values:

Status Meaning
deploying Deployment in progress; the deploy handler owns this transition
running Docker container is alive
failed Deployment or container creation failed
dead Docker container has stopped or been removed
unreachable Agent on the VM could not be reached — status unknown
Terminal window
swarm container info <alias-or-id>

Accepts the container alias or UUID.

ID: a1b2c3d4e5f67890
Alias: dev
VM: my-server (00a1b2c3-d4e5-6f78-9a0b-c1d2e3f4a5b6)
Status: running
Container ID: docker-abc123
Created: 2026-02-07 14:35:00

The CLI does not yet provide first-class shell or port-forward commands in this release. To open a shell:

Terminal window
ssh root@<vm-ip> -- docker exec -it <docker-id> bash

<docker-id> is the CONTAINER ID from swarm container list. For port forwarding, use SSH local port forwarding directly:

Terminal window
ssh -L 3000:<container-bridge-ip>:3000 root@<vm-ip>

For HTTP services, prefer the container HTTP proxy, which does not require SSH on the caller side.

Terminal window
swarm container rename dev dev-backend

Aliases must match [A-Za-z0-9][A-Za-z0-9_-]{0,62} and be unique.

Terminal window
swarm container rm <alias-or-id>

Stops the container on the remote VM via the agent and removes it from the registry. If the VM no longer exists, the container is removed from the registry with a warning.