mando-cli: Docker Container Lifecycle

Overview

Implemented real Docker container management for mando up, mando down, and mando volume commands using the bollard 0.19 crate. Previously these commands were stubs or wired to dead code.

DockerClient (src/runtime/docker_client.rs)

Wraps bollard::Docker with container lifecycle methods:

MethodPurpose
ensure_running(spec, force)Pull image if needed, create + start container. If force, recreates existing.
find_container(name)Find a mando-labeled container by name
list_mando_containers(all)List all containers with mando.managed=true label
stop_and_remove(name)Stop (10s timeout) then force-remove container
stop_all_mando()Stop and remove all mando-managed containers
list_volumes_for(prefix)List Docker volumes matching a name prefix
remove_volume(name)Remove a Docker volume
ensure_image(image)Inspect locally, pull if missing

All managed containers get the mando.managed=true label for identification.

Container Specs (src/runtime/infra.rs)

ServiceImagePortsVolumesRequired
postgrespostgres:16-alpine5432:5432mando-pgdataYes
wiremockwiremock/wiremock:3x-alpine8080:8080noneNo (--only wiremock)

ContainerSpec struct: name, image, ports Vec<(u16, u16)>, env, volumes (bind mount strings), network.

Containers get restart_policy: unless-stopped and bind to 0.0.0.0.

Command Wiring

mando up [--only <svc>] [--force] — starts required infra + any --only optional services. Shows port mappings in output. Profile-based app service startup not yet implemented.

mando down — stops all mando-managed containers. Reports each stopped container.

mando volume list — shows volumes grouped by service prefix.

mando volume clear [service|all] — removes matching volumes.

bollard 0.19 API Notes

  • start_container, list_volumes, remove_volume no longer accept generic type params directly. Use None::<OptionsType> for the options parameter.
  • ContainerSummaryStateEnum doesn’t implement Default — need .map(|s| s.to_string()) instead of .unwrap_or_default().
  • VolumeListResponse has .volumes directly (no .body wrapper).
  • BuildImageOptions and CreateImageOptions are deprecated but still work — suppressed with #[allow(deprecated)].

What’s Still Missing

  • mando up --profile <name> app service startup (noted in up.rs with a warning)
  • Status command showing container health/state
  • Network creation for multi-container communication

See also: