Skip to content

Add volume removal when removing accessories#1751

Open
cyppe wants to merge 1 commit intobasecamp:mainfrom
cyppe:feat/remove-accessory-volumes
Open

Add volume removal when removing accessories#1751
cyppe wants to merge 1 commit intobasecamp:mainfrom
cyppe:feat/remove-accessory-volumes

Conversation

@cyppe
Copy link
Copy Markdown

@cyppe cyppe commented Jan 11, 2026

Summary

When running kamal accessory remove, directories created via the directories: configuration are deleted from the host, but Docker volumes specified via the volumes: configuration are not removed. This creates an inconsistency in behavior.

Arguably, deleting host-mounted directories is more drastic than deleting Docker-managed volumes, yet only the former happens automatically. This PR adds volume deletion to match the directory deletion behavior, making kamal accessory remove fully clean up all accessory-related storage.

Example Output

Before this change, kamal accessory remove postgres-backup -y would output:

INFO Running docker container stop generate-postgres-backup on 192.168.1.86
INFO Running docker container prune --force --filter label=service=generate-postgres-backup on 192.168.1.86
INFO Running docker image rm --force timescale/timescaledb:latest-pg18 on 192.168.1.86
INFO Running /usr/bin/env rm -rf generate-postgres-backup on 192.168.1.86

After this change, an additional step removes Docker volumes:

INFO Running docker container stop generate-postgres-backup on 192.168.1.86
INFO Running docker container prune --force --filter label=service=generate-postgres-backup on 192.168.1.86
INFO Running docker image rm --force timescale/timescaledb:latest-pg18 on 192.168.1.86
INFO Running /usr/bin/env rm -rf generate-postgres-backup on 192.168.1.86
INFO Running docker volume rm generate-postgres-backups on 192.168.1.86  # <-- NEW

Behavior

Given an accessory configured with:

accessories:
  mysql:
    image: mysql:8.0
    host: 1.1.1.1
    volumes:
      - mysql-data:/var/lib/mysql        # Named volume - will be removed
      - /host/path:/container/path       # Bind mount - ignored (not a Docker volume)
    directories:
      - data:/var/lib/data               # Already removed by existing code

After this change, kamal accessory remove mysql will:

  1. Stop the container (existing)
  2. Remove the container (existing)
  3. Remove the image (existing)
  4. Remove the service directory (existing)
  5. Remove Docker volumes (docker volume rm mysql-data) - NEW

Only named Docker volumes are removed. Bind mounts (paths starting with /) are correctly excluded since they're not Docker volumes.

Changes

  • Add volume_names method to Configuration::Accessory that extracts Docker volume names from the volumes: config (excluding bind mounts which use absolute paths starting with /)
  • Add remove_volumes command to Commands::Accessory that runs docker volume rm for the accessory's named volumes
  • Add remove_volumes CLI method and call it in remove_accessory
  • Update the remove command description and confirmation message to mention volumes
  • Add tests for the new functionality

When running `kamal accessory remove`, directories created via the
`directories:` configuration are deleted, but Docker volumes created
via the `volumes:` configuration are not. This seems inconsistent,
especially since deleting host-mounted directories is arguably more
drastic than deleting Docker volumes.

This change adds volume deletion to match the directory deletion
behavior:

- Add `volume_names` method to Configuration::Accessory that extracts
  Docker volume names from the `volumes:` config (excluding bind mounts
  which start with `/`)
- Add `remove_volumes` command to Commands::Accessory that runs
  `docker volume rm` for the accessory's named volumes
- Add `remove_volumes` CLI method and call it in `remove_accessory`
- Update the remove confirmation message to mention volumes
- Add tests for the new functionality

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant