volume/remove
Permanently remove a Docker volume and all data it contains from the host.
Irreversible data deletion: Volume removal permanently and immediately deletes all data stored in the volume. There is no undo. Always confirm that a backup has been completed and verified before triggering this operation.
When to Use
- Tenant offboarding: After confirming that the tenant's data has been exported and a verified backup exists, remove the tenant database volume as the final step of the offboarding workflow.
- CI/CD teardown: Remove ephemeral test data volumes after a CI test suite completes to prevent unbounded storage growth on shared build agents.
- Orphan cleanup: Remove volumes identified by a
volume/listaudit as having no associated containers, after confirming they hold no active data.
Configuration
Connection
| Field | Type | Default | Description |
|---|---|---|---|
dockerHost | string | unix:///var/run/docker.sock | Docker daemon socket path or TCP endpoint. |
connectionType | string | unixsocket | One of: unixsocket, tcp, tcptls. |
tlsCertPath | string | — | TLS certificate directory. Required for tcptls. optional |
timeoutSeconds | int | 30 | Operation timeout. optional |
Operation Fields
| Field | Type | Badge | Description |
|---|---|---|---|
Name | string | required | Name of the volume to remove. |
Sample Configuration
{
"resource": "volume",
"operation": "remove",
"connection": {
"dockerHost": "unix:///var/run/docker.sock",
"connectionType": "unixsocket"
},
"Name": "db-tenant-0042"
}
Validation Errors
| Error Code | Condition | Resolution |
|---|---|---|
MISSING_INPUT | Name field is empty. | Provide the volume name to remove. |
NOT_FOUND | Volume does not exist (already removed or never created). | Treat as success in cleanup workflows — the volume is already absent. |
CONFLICT | Volume is currently in use by a container (running or stopped). | Stop and remove the container with container/stop and container/remove first. |
CONFIG_ERROR | Connection settings malformed. | Check dockerHost and connectionType. |
DOCKER_API_ERROR | Unexpected daemon error. | Check Docker daemon logs on the host. |
Output
Success Port
| Field | Type | Description |
|---|---|---|
status | string | "ok" when the volume is removed successfully. |
resource | string | "volume" |
operation | string | "remove" |
name | string | The volume name that was removed. |
Error Port
Fires when removal fails. The most common error codes are CONFLICT (container still using the volume) and NOT_FOUND (volume already absent).
Sample Output
{
"status": "ok",
"resource": "volume",
"operation": "remove",
"name": "db-tenant-0042"
}
Expression Reference
| Expression | Returns |
|---|---|
{{ $output.status }} | "ok" — confirm removal before writing to audit log. |
{{ $output.name }} | The removed volume name — include in offboarding audit record. |
{{ $output.errorCode }} | "CONFLICT" — indicates containers still reference this volume. |
Node Policies & GuardRails
| Policy | Enforcement |
|---|---|
| Never expose Docker daemon TCP without TLS | Use tcptls for remote connections. Plain tcp is blocked in production GuardRail profiles. |
| Store TLS certificates in Credentials Manager | Reference tlsCertPath via {{ $credentials.dockerTlsCertPath }}. |
| Always confirm backup before removing volumes | Place a human-in-the-loop approval node or a backup-status check node immediately before volume/remove in any offboarding workflow. |
| Stop and remove dependent containers first | Calling volume/remove while a container still mounts the volume returns CONFLICT. Always call container/stop and container/remove first. |
| Never interpolate user input into the Name field | Volume names must come from trusted workflow variables, never raw user-supplied input. |
| Restrict container/exec to approved commands | Arbitrary exec access is root-equivalent. GuardRail exec policies restrict allowed command prefixes. |
Examples
Example 1 — Tenant Offboarding with Backup Gate
Stop the tenant container, remove it, confirm backup success, then remove the volume. Each step gates the next.
// Step 1 — container/stop
{ "resource": "container", "operation": "stop", "ContainerId": "db-{{ $trigger.tenantId }}" }
// Step 2 — container/remove
{ "resource": "container", "operation": "remove", "ContainerId": "db-{{ $trigger.tenantId }}" }
// Step 3 — HTTP Request: verify backup job completed successfully
// Step 4 — Approval gate (human-in-the-loop)
// Step 5 — volume/remove
{
"resource": "volume",
"operation": "remove",
"Name": "db-tenant-{{ $trigger.tenantId }}"
}
Example 2 — CI Test Volume Cleanup
After a test suite completes, remove all volumes whose names match the CI run prefix.
// After volume/list, filter for volumes matching "ci-run-" prefix:
// Loop: for each matched volume:
{
"resource": "volume",
"operation": "remove",
"Name": "{{ $loopItem.Name }}"
}
// Treat NOT_FOUND as success (already cleaned up by previous run)
Example 3 — Safe Orphan Cleanup
Remove only volumes that have no containers listed in their usage status, ensuring no live data is deleted.
// Step 1 — volume/list
// Step 2 — For each volume, call volume/inspect to check Status.RefCount
// Step 3 — Only remove if RefCount === 0 (no containers reference the volume)
{
"resource": "volume",
"operation": "remove",
"Name": "{{ $loopItem.Name }}"
}