daoflow deploy
Deploy a service to a target server. This is the primary command for shipping code.
Usage
daoflow deploy [options]
Options
| Flag | Required | Description |
|---|---|---|
--service <id> | No | Existing DaoFlow service ID to deploy |
--server <id> | No | Target server ID. Required for direct --compose deploys |
--compose <path> | No | Path to compose.yaml for a direct Compose deployment |
--context <path> | — | Upload root for compose-local inputs |
--commit <sha> | — | Commit SHA override for a service deploy |
--image <ref> | — | Image tag override for a service deploy |
--preview-branch <name> | — | Target a preview deployment for a registered compose service |
--preview-pr <number> | — | Associate the preview with a pull request |
--preview-close | — | Destroy the targeted preview stack instead of deploy |
--dry-run | — | Preview plan without executing (exit code 3) |
--no-prompt | — | Skip interactive prompts during direct Compose upload preparation |
--yes | — | Skip confirmation prompt (required for non-interactive execution) |
--json | — | Structured JSON output |
Required Scope
deploy:start
Examples
Docker Compose Preview
# Preview the deployment plan
daoflow deploy \
--server srv_production \
--compose ./compose.yaml \
--context . \
--dry-run
# Execute the deployment
daoflow deploy \
--server srv_production \
--compose ./compose.yaml \
--context . \
--yes
For direct compose deploys, --context must include every compose-relative local input that needs bundling. DaoFlow validates local build.context paths, bundleable build.additional_contexts, file-backed build secrets, and local env_file assets before prompting or uploading anything. If the chosen root is too narrow, the CLI exits with INVALID_INPUT.
You do not need to create a project first. DaoFlow derives the stack name from the Compose document, creates the project, production environment, and service on the first deployment, and reuses that scope on later deployments.
Image Deployment
daoflow deploy \
--service svc_my_api \
--image ghcr.io/myorg/my-api:v1.2.3 \
--yes
Compose Preview Deployment
daoflow deploy \
--service svc_preview \
--preview-branch feature/login \
--preview-pr 42 \
--dry-run
daoflow deploy \
--service svc_preview \
--preview-branch feature/login \
--preview-pr 42 \
--yes
daoflow deploy \
--service svc_preview \
--preview-branch feature/login \
--preview-pr 42 \
--preview-close \
--yes
Preview targeting is supported only for registered compose services with config.preview.enabled. Direct --compose uploads do not support preview flags.
If the backing project also has webhook auto-deploy configured, DaoFlow can queue the same preview deploy and cleanup actions automatically from GitHub pull request or GitLab merge request lifecycle events. Manual daoflow deploy --service ... --preview-* remains the explicit fallback for retries and operator-driven cleanup.
With Environment Variables
daoflow deploy \
--service svc_my_app \
--image my-app:latest \
--yes
JSON Output
{
"ok": true,
"deploymentId": "dep_abc123",
"status": "queued",
"service": "svc_my_app",
"sourceType": "service",
"createdAt": "2026-03-15T10:30:00Z"
}
Dry Run
When using --dry-run with --service, the CLI calls the real planning-lane deployment planner and returns that server-side preview without executing anything:
daoflow deploy --service svc_my_app --dry-run --json
{
"ok": true,
"data": {
"dryRun": true,
"plan": {
"isReady": true,
"service": {
"name": "svc_my_app",
"projectName": "Acme",
"environmentName": "production"
},
"target": {
"serverName": "prod",
"targetKind": "docker-swarm-manager",
"imageTag": "ghcr.io/acme/my-app:stable"
},
"currentDeployment": null,
"preflightChecks": [{ "status": "ok", "detail": "Resolved target server." }],
"steps": ["Freeze runtime spec", "Dispatch execution"],
"executeCommand": "daoflow deploy --service svc_123 --yes"
}
}
}
When using --dry-run with --compose, the CLI calls the planning-lane composeDeploymentPlan route. The CLI still computes local context bundle metadata first so the server-side plan can include upload size, included override files, and local build-context requirements without mutating anything.
daoflow deploy --compose ./compose.yaml --server srv_prod --dry-run --json
{
"ok": true,
"data": {
"dryRun": true,
"plan": {
"isReady": true,
"deploymentSource": "uploaded-context",
"project": { "id": null, "name": "preview-stack", "action": "create" },
"environment": { "id": null, "name": "production", "action": "create" },
"service": {
"id": null,
"name": "preview-stack",
"action": "create",
"sourceType": "compose"
},
"target": {
"serverId": "srv_prod",
"serverName": "prod",
"serverHost": "203.0.113.10",
"targetKind": "docker-swarm-manager",
"composePath": "./compose.yaml",
"contextPath": ".",
"requiresContextUpload": true,
"localBuildContexts": [
{ "serviceName": "web", "context": ".", "dockerfile": "Dockerfile" }
],
"contextBundle": { "fileCount": 42, "sizeBytes": 13824, "includedOverrides": [".env"] }
},
"preflightChecks": [
{ "status": "ok", "detail": "Target server resolved to prod (203.0.113.10)." }
],
"steps": [
"Freeze the compose file and local build-context manifest",
"Bundle the local build context while respecting .dockerignore rules",
"Upload the staged archive and compose file to the DaoFlow control plane"
],
"executeCommand": "daoflow deploy --compose ./compose.yaml --server srv_prod --context . --yes"
}
}
}
Exit code is 3 for successful dry runs.
For Swarm-backed compose services or direct compose uploads to docker-swarm-manager targets,
dry-run output now makes the stack workflow explicit before execution. The server-side steps and
checks also call out when DaoFlow will use docker stack deploy semantics instead of docker compose up.
Current Support
daoflow deploy --service <id> --yesdeploys an existing DaoFlow service definition.daoflow deploy --compose ./compose.yaml --server <id> --yesuploads the Compose file directly.- If the Compose file uses local build inputs such as
build.context,build.additional_contexts, local build secret files, or localenv_fileassets, the CLI bundles the required files, respects.dockerignore, uploads them, and the server executes the build remotely.
Safety
--yesis required for non-interactive execution- Without
--yes, the CLI prompts for confirmation --dry-runalways works, even with read-only tokens- Duplicate deployments are prevented with
--idempotency-key