Generated by qqd docs.
usage:
qqd [--help]
qqd help [command]
qqd plan -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--output json] [services...]
qqd init -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--force-unlock] [services...]
qqd deploy -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--no-build] [--approve] [--dry-run] [--config-only] [--force-unlock] [services...]
qqd build -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--force-unlock] [services...]
qqd update -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--approve] [service[=version]...]
qqd status -c <config> [-c <overlay>...] [-t <target>] [--output json]
qqd logs -c <config> [-c <overlay>...] [-t <target>] [services...]
qqd rollback -c <config> [-c <overlay>...] [-t <target>] [--force-unlock] [service]
qqd history -c <config> [-c <overlay>...] [-t <target>]
qqd stop -c <config> [-c <overlay>...] [-t <target>] [services...]
qqd start -c <config> [-c <overlay>...] [-t <target>] [services...]
qqd destroy -c <config> [-c <overlay>...] [-t <target>] [--force-unlock]
qqd clean -c <config> [-c <overlay>...] [-t <target>]
qqd doctor -c <config> [-c <overlay>...] [-t <target>]
qqd validate -c <config> [-c <overlay>...]
qqd convert -c <input> [-o <output>] [--format yaml|json|hocon]
qqd migrate -c <config> --from <source> [--to podman] [--stack <name>] [--dry-run] [--yes]
qqd import -f <docker-compose.yaml> [--env <.env>] [--format yaml|json|hocon] [--host <host>] [--user <user>] [--ssh-key <key>] [-o <output>]
qqd man
qqd docs [config] [--format markdown] [-o <path>]
qqd manifest [--format json|md] [-o <path>]
plan: show deployment plan without executinginit: first-time setup on target(s)deploy: idempotent deploy: build/pull missing images and apply changed servicesbuild: build/pull images only, no deploy/restartupdate: bump/set image version(s) and redeploy updated servicesstatus: show service state/image/uptime on target(s)logs: stream container logsrollback: restore previous release (or rollback single service)history: show deployment release history on target(s)stop: stop service unitsstart: start service unitsdestroy: stop/disable units and remove generated unit filesclean: remove project containers and unused images from targetsdoctor: check target environment for common problemsvalidate: check config for errors without deployingconvert: convert config between formats (yaml, json, hocon)migrate: migrate a running Compose or Swarm stack to Podman-backed qqdimport: generate qqd config from a docker-compose.yamlman: open installed manual page (same as man qqd)docs: generate CLI or configuration documentationmanifest: emit the full qqd surface (commands, flags, config schema, pitfalls) for AI agents and tooling
qqd plan -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--output json] [services...]
show deployment plan without executing
- displays what deploy would do without making any changes
- shows per-target breakdown of:
-
- services that will be deployed
-
- images and build actions
-
- deployment mode (standard, slot-based, replicated)
-
- risks (e.g. exposed-no-health, mutable-image-tag, caddy-tcp-passthrough)
- use --output json for machine-readable output. The JSON shape is:
- { project, runtime, proxy, sync, mode, targets[], risks[] }
- where each risk has { level (info|warn|danger), code, message, target?, service? }
- CI gates can fail when any risk has level="danger":
- qqd plan -c app.yaml --output json | jq -e '.risks | map(select(.level=="danger")) | length == 0'
qqd init -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--force-unlock] [services...]
first-time setup on target(s)
- first-time setup: clone repo, create dirs, build/pull images, install units, start
- pipeline:
- SSH to target
-
|-- mkdir -p <repo_dir> -
|-- git clone <repo> (if not cloned yet) -
|-- git fetch --all && git reset --hard origin/<branch> -
|-- mkdir -p <dirs> (target directories) -
|-- for each service: -
| image missing + has dockerfile --> build -
| image missing + no dockerfile --> pull -
| image exists --> skip -
|-- write unit files to systemd directory -
|-- systemctl daemon-reload -
|-- systemctl start <all units> -
'-- verify: systemctl is-active <each unit>
qqd deploy -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--no-build] [--approve] [--dry-run] [--config-only] [--force-unlock] [services...]
idempotent deploy: build/pull missing images and apply changed services
- idempotent: only builds/pulls missing images, only applies changed services
- shows a plan and asks for confirmation before proceeding.
- use --approve to skip the confirmation prompt (for CI/scripts).
- use --dry-run to show the plan without executing any changes.
- use --no-build to skip building dockerfile services (still pulls, updates config, restarts).
- use --config-only to skip source sync and image build (only update config, env, expose, restart).
- use --force-unlock to take the deploy lock even if another holder is recorded on the target
- (only safe if you are sure no other deploy is in progress).
- full deploy (no service args) removes services deleted from the config.
- partial deploy (e.g. "qqd deploy server") leaves other services untouched.
- pipeline:
- SSH to target
-
|-- mkdir -p <repo_dir> -
|-- git clone (if not cloned) or git fetch + reset -
|-- mkdir -p <dirs> -
|-- for each service: -
| image exists --> skip (no build, no restart) -
| image missing + has dockerfile --> build --> mark changed -
| image missing + no dockerfile --> pull --> mark changed -
|-- if sync=upload + services have context: upload only context dirs -
| otherwise: upload/sync full project -
|-- write unit files, daemon-reload -
|-- remove stale unit files (full deploy: all removed services; -
| partial deploy: only replica/mode changes for targeted services) -
|-- detect config changes (unit files + proxy container) -
|-- systemctl start <all units> -
|-- apply changed services (slot, rolling, or restart in place) -
'-- verify: systemctl is-active <each unit> - if install/restart fails and a previous release exists,
- qqd auto-rolls back to the last successful release.
- hooks: pre_deploy and post_deploy run at deployment boundaries
qqd build -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--force-unlock] [services...]
build/pull images only, no deploy/restart
- build/pull images without restarting any services
- pipeline:
- SSH to target
-
|-- git fetch + reset (sync source) -
|-- mkdir -p <dirs> -
|-- for each service: -
| image exists --> skip -
| has dockerfile --> build -
| no dockerfile --> pull -
'-- print summary of built/pulled images - no unit files are written, no services are restarted
qqd update -c <config> [-c <overlay>...] [-t <target>] [--rebuild] [--approve] [service[=version]...]
bump/set image version(s) and redeploy updated services
- with no services: auto-bumps all buildable services (those with a dockerfile)
- with services: bumps or sets versions for the listed services
- pipeline:
- LOCAL: read config file
-
|-- for each service to update: -
| auto-bump: increment rightmost number (1.44 -> 1.45, 0.1-b7 -> 0.1-b8) -
| explicit: set to provided version (server=2.0) -
|-- rewrite image tags in config file in-place -
'-- print updated versions - then run DEPLOY for the updated services only:
-
SSH to target -
|-- git fetch + reset -
|-- build/pull new image versions (old versions still exist, new ones don't) -
|-- write unit files, daemon-reload -
|-- restart updated services -
|-- verify -
'-- on failure: auto-rollback to previous release (if available)
qqd status -c <config> [-c <overlay>...] [-t <target>] [--output json]
show service state/image/uptime on target(s)
- check connectivity and print service status for each target
- use --output json for machine-readable JSON output
- output format: image (YYYY-MM-DD HH:MM:SS UTC, up Xh Ym)
- pipeline:
- SSH to target
-
|-- ls <unit directory> (connectivity check + slot detection) -
'-- batched query for all services: -
|-- systemctl is-active <unit> -
'-- <runtime> inspect <container> (image name, creation time)
qqd logs -c <config> [-c <overlay>...] [-t <target>] [services...]
stream container logs
- stream last 200 lines and follow new output
- without service args, streams all services
- replicated services stream all replicas
- multiple containers are prefixed with the container name
- pipeline:
- SSH to target
-
'-- <runtime> logs --tail 200 -f <container> (per container, in parallel)
qqd rollback -c <config> [-c <overlay>...] [-t <target>] [--force-unlock] [service]
restore previous release (or rollback single service)
- rolls back to the previous release on the target
- with a service name, rolls back only that service
- without a service name, rolls back all services to the previous release
- the previous release's images are pulled if not already on the target
- the rollback is saved as a new release in the history
- note: deploy and update auto-rollback on failure when a previous
- release exists. this command is for manual rollback.
qqd history -c <config> [-c <overlay>...] [-t <target>]
show deployment release history on target(s)
- lists recent releases stored on each target
- shows release ID, timestamp, and service images
- the most recent release is marked with →
qqd stop -c <config> [-c <overlay>...] [-t <target>] [services...]
stop service units
- stop selected or all service units (preserves unit files and images)
- pipeline:
- SSH to target
-
'-- systemctl stop <service units>
qqd start -c <config> [-c <overlay>...] [-t <target>] [services...]
start service units
- start previously stopped service units
- pipeline:
- SSH to target
-
|-- systemctl start <network unit> -
'-- systemctl start <service units>
qqd destroy -c <config> [-c <overlay>...] [-t <target>] [--force-unlock]
stop/disable units and remove generated unit files
- fully remove project from target (images are NOT removed)
- pipeline:
- SSH to target
-
|-- stop all units (systemctl stop, tolerates missing) -
|-- disable all units (systemctl disable) -
|-- remove unit files -
|-- clean up proxy config (~/.config/qqd/<project>/) -
'-- reload systemd daemon
qqd clean -c <config> [-c <overlay>...] [-t <target>]
remove project containers and unused images from targets
- removes stopped containers and stale images associated with the project
- pipeline:
- SSH to target
-
|-- list and remove containers matching <project>-* -
|-- list and remove images matching <project>-* -
'-- prune dangling (<none>) images
qqd doctor -c <config> [-c <overlay>...] [-t <target>]
check target environment for common problems
- runs diagnostic checks on deployment targets
- checks:
-
- SSH connectivity
-
- Podman availability
-
- systemd session
-
- unit directory exists
-
- disk space
-
- user lingering (Podman only)
qqd validate -c <config> [-c <overlay>...]
check config for errors without deploying
- validates the configuration file for common errors
- checks:
-
- service references in depends_on
-
- circular dependency detection
-
- port range validation
-
- TLS configuration completeness
-
- health check port inference
-
- build strategy requirements
-
- mutable image tag warnings
qqd convert -c <input> [-o <output>] [--format yaml|json|hocon]
convert config between formats (yaml, json, hocon)
- reads a qqd config file and outputs it in a different format
- format is auto-detected from output file extension, or set with --format
- without -o, prints to stdout
qqd migrate -c <config> --from <source> [--to podman] [--stack <name>] [--dry-run] [--yes]
migrate a running Compose or Swarm stack to Podman-backed qqd
- --from compose stop docker-compose stack, deploy with qqd
- --from swarm stop docker swarm stack, leave swarm, deploy with qqd
- --to is optional and must be podman (the only supported runtime)
- --stack sets the compose/swarm stack name (defaults to project name)
- --dry-run prints every destructive action without executing it. recommended
-
for the FIRST run on any production-like target. - --yes (or -y) skips the destructive-action confirmation prompt. only use
-
when you have already validated the migration with --dry-run. - images are transferred from Docker to Podman automatically
- volume ownership is fixed when migrating to rootless podman
- safety notes:
-
- swarm migration runs
docker swarm leave --force. if this node is part
- swarm migration runs
-
of a multi-node swarm, the entire swarm is affected, not just this stack. -
- migrating to podman runs
sudo chown -Ron every service volume host path.
- migrating to podman runs
-
if other workloads use the same paths, they will be affected too. -
docker network prune -fis invoked, which removes ALL unused networks
-
on the host, not just those in your project. - examples:
- qqd migrate -c app.yaml --from compose --stack my-stack --dry-run
- qqd migrate -c app.yaml --from swarm --stack my-stack --to podman --yes
qqd import -f <docker-compose.yaml> [--env <.env>] [--format yaml|json|hocon] [--host <host>] [--user <user>] [--ssh-key <key>] [-o <output>]
generate qqd config from a docker-compose.yaml
- parses a docker-compose.yaml and generates a qqd config file
- supports: services, images, build contexts, volumes, environment, ports, depends_on, commands
- env vars from --env file are expanded (${VAR:-default} syntax)
- output format is auto-detected from extension, or set with --format (yaml, json, hocon)
- after generating, review the config and deploy:
- qqd import -f docker-compose.yaml --host 192.0.2.10 --user ec2-user -o app.yaml
- qqd deploy -c app.yaml
qqd man
open installed manual page (same as man qqd)
- opens the qqd manual page with your local
mancommand
qqd docs [config] [--format markdown] [-o <path>]
generate CLI or configuration documentation
- without arguments: prints CLI command reference
- with 'config': prints full configuration reference (all fields, types, defaults)
- default format is markdown
- by default output is stdout; use -o to write a file
qqd manifest [--format json|md] [-o <path>]
emit the full qqd surface (commands, flags, config schema, pitfalls) for AI agents and tooling
- prints a single structured document covering every command, flag,
- config field, output format, lifecycle backend, and known pitfall.
- the JSON shape is stable across patch releases — use it as the
- entry point for any agent that drives qqd.
- primary sources:
-
- commands <- commandSpecs() in this file
-
- common flags <- commonFlagRegistry() in manifest.go
-
- config <- reflection over qqd:-tagged structs in types.go
-
- guidance <- curated registries in manifest.go
- prefer this over
qqd docswhen consuming programmatically.