chore(docker): add interactive cleanup menu
This commit is contained in:
parent
8f449a5ee5
commit
e619fa8eb5
@ -39,6 +39,7 @@ For a single-host prototype, use Docker Compose with the repo root [`docker-comp
|
||||
cp .env.example .env
|
||||
./scripts/prototype-up.sh
|
||||
pnpm prototype:self-test
|
||||
pnpm docker:clean
|
||||
```
|
||||
|
||||
See [docs/PROTOTYPE_DEPLOYMENT.md](docs/PROTOTYPE_DEPLOYMENT.md) for the required environment variables and day-to-day commands.
|
||||
|
||||
@ -65,10 +65,13 @@ docker compose logs -f mailpit
|
||||
pnpm prototype:self-test
|
||||
./scripts/prototype-self-test.sh
|
||||
docker compose down
|
||||
pnpm docker:clean
|
||||
```
|
||||
|
||||
`pnpm prototype:self-test` is the stable host-side smoke-test entrypoint. It runs the same end-to-end check as the underlying shell script, but gives ops a single repo-level command to remember.
|
||||
|
||||
`pnpm docker:clean` opens an interactive Docker cleanup menu. Use it for escalating cleanup levels from status-only and compose shutdown through repo volume cleanup, image pruning, and full Docker volume pruning.
|
||||
|
||||
The Cosmos Data Explorer is exposed on `http://localhost:1234`.
|
||||
Azurite Blob Storage is exposed on `http://localhost:10000`.
|
||||
Mailpit SMTP listens on `localhost:1025` and the Mailpit inbox UI is exposed on `http://localhost:8025`.
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md,yml,yaml}\"",
|
||||
"audit": "pnpm -r audit --audit-level moderate",
|
||||
"clean": "pnpm -r exec rm -rf dist",
|
||||
"docker:clean": "./scripts/docker-clean.sh",
|
||||
"dns:godaddy:bytelyst": "./scripts/godaddy-sync-bytelyst-dns.sh",
|
||||
"prototype:self-test": "./scripts/prototype-self-test.sh",
|
||||
"release": "./scripts/gitea/release-packages.sh",
|
||||
|
||||
300
scripts/docker-clean.sh
Executable file
300
scripts/docker-clean.sh
Executable file
@ -0,0 +1,300 @@
|
||||
#!/usr/bin/env bash
|
||||
# docker-clean.sh - Interactive Docker cleanup for the ByteLyst platform prototype.
|
||||
set -euo pipefail
|
||||
|
||||
RED=$'\033[0;31m'
|
||||
GREEN=$'\033[0;32m'
|
||||
YELLOW=$'\033[1;33m'
|
||||
CYAN=$'\033[0;36m'
|
||||
BOLD=$'\033[1m'
|
||||
DIM=$'\033[2m'
|
||||
NC=$'\033[0m'
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
log() { echo -e "${CYAN}[docker-clean]${NC} $*"; }
|
||||
ok() { echo -e "${GREEN}OK:${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}WARN:${NC} $*"; }
|
||||
err() { echo -e "${RED}ERROR:${NC} $*" >&2; }
|
||||
|
||||
require_docker() {
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
err "Docker CLI is not installed or not on PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
err "Docker daemon is not reachable. Start Docker Desktop or your Docker daemon and try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker compose version >/dev/null 2>&1; then
|
||||
err "Docker Compose plugin is not available. Install/update Docker Desktop or the docker compose plugin."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_cmd() {
|
||||
echo -e "${DIM}$*${NC}"
|
||||
"$@"
|
||||
}
|
||||
|
||||
confirm() {
|
||||
local prompt="$1"
|
||||
read -r -p "$(echo -e "${BOLD}${prompt}${NC} [y/N] ")" answer
|
||||
case "${answer:-}" in
|
||||
y|Y|yes|YES) return 0 ;;
|
||||
* ) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
compose_status() {
|
||||
log "Compose services in $REPO_ROOT"
|
||||
cd "$REPO_ROOT"
|
||||
run_cmd docker compose ps
|
||||
echo ""
|
||||
log "Docker disk usage"
|
||||
run_cmd docker system df
|
||||
}
|
||||
|
||||
stop_compose() {
|
||||
log "Stopping compose services"
|
||||
cd "$REPO_ROOT"
|
||||
run_cmd docker compose stop
|
||||
}
|
||||
|
||||
down_compose() {
|
||||
log "Removing compose containers and networks"
|
||||
cd "$REPO_ROOT"
|
||||
run_cmd docker compose down --remove-orphans
|
||||
}
|
||||
|
||||
down_compose_with_volumes() {
|
||||
cd "$REPO_ROOT"
|
||||
run_cmd docker compose down --remove-orphans --volumes
|
||||
}
|
||||
|
||||
safe_prune() {
|
||||
log "Pruning stopped containers, unused networks, dangling images, and build cache"
|
||||
run_cmd docker container prune --force
|
||||
run_cmd docker network prune --force
|
||||
run_cmd docker image prune --force
|
||||
run_cmd docker builder prune --force
|
||||
}
|
||||
|
||||
unused_image_prune() {
|
||||
run_cmd docker image prune --all --force
|
||||
run_cmd docker builder prune --all --force
|
||||
}
|
||||
|
||||
full_prune() {
|
||||
run_cmd docker system prune --all --volumes --force
|
||||
}
|
||||
|
||||
builder_prune() {
|
||||
log "Pruning Docker builder cache"
|
||||
run_cmd docker builder prune --all --force
|
||||
}
|
||||
|
||||
show_menu() {
|
||||
cat <<EOF
|
||||
|
||||
${BOLD}Docker Cleanup Menu${NC}
|
||||
|
||||
Repo: $REPO_ROOT
|
||||
|
||||
${BOLD}1${NC}) Status only
|
||||
Show compose services and Docker disk usage.
|
||||
|
||||
${BOLD}2${NC}) Stop compose services
|
||||
Keeps containers, networks, volumes, and images.
|
||||
|
||||
${BOLD}3${NC}) Remove compose containers and networks
|
||||
Runs compose down with orphan cleanup. Keeps repo volumes.
|
||||
|
||||
${BOLD}4${NC}) Remove compose containers, networks, and repo compose volumes
|
||||
Deletes prototype state for this repo's compose project.
|
||||
|
||||
${BOLD}5${NC}) Safe global prune
|
||||
Removes stopped containers, unused networks, dangling images, and build cache.
|
||||
|
||||
${BOLD}6${NC}) Deeper image/cache prune
|
||||
Removes all unused images and build cache.
|
||||
|
||||
${BOLD}7${NC}) Full global Docker prune
|
||||
Removes all unused Docker resources, including unused volumes.
|
||||
|
||||
${BOLD}8${NC}) Builder cache only
|
||||
Removes Docker build cache.
|
||||
|
||||
${BOLD}q${NC}) Quit
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
describe_level() {
|
||||
case "$1" in
|
||||
1)
|
||||
cat <<EOF
|
||||
|
||||
${BOLD}You selected: Status only${NC}
|
||||
|
||||
This will:
|
||||
- Show this repo's Docker Compose services.
|
||||
- Show Docker disk usage.
|
||||
- Not stop, remove, or prune anything.
|
||||
|
||||
After this, everything will remain exactly as it is.
|
||||
EOF
|
||||
;;
|
||||
2)
|
||||
cat <<EOF
|
||||
|
||||
${BOLD}You selected: Stop compose services${NC}
|
||||
|
||||
This will:
|
||||
- Stop containers from this repo's Docker Compose stack.
|
||||
- Keep the containers, networks, images, and volumes.
|
||||
- Preserve prototype data in Cosmos, Azurite, and Mailpit volumes.
|
||||
|
||||
After this, the stack will be stopped but can be resumed with:
|
||||
./scripts/prototype-up.sh
|
||||
EOF
|
||||
;;
|
||||
3)
|
||||
cat <<EOF
|
||||
|
||||
${BOLD}You selected: Remove compose containers and networks${NC}
|
||||
|
||||
This will:
|
||||
- Stop and remove this repo's compose containers.
|
||||
- Remove compose networks and orphan containers.
|
||||
- Keep repo compose volumes.
|
||||
- Preserve prototype data in Cosmos, Azurite, and Mailpit volumes.
|
||||
|
||||
After this, containers will be recreated the next time you start the prototype.
|
||||
EOF
|
||||
;;
|
||||
4)
|
||||
cat <<EOF
|
||||
|
||||
${BOLD}You selected: Remove compose containers, networks, and repo compose volumes${NC}
|
||||
|
||||
This will:
|
||||
- Stop and remove this repo's compose containers.
|
||||
- Remove compose networks and orphan containers.
|
||||
- Delete this repo's compose volumes.
|
||||
- Delete prototype state stored in local Cosmos, Azurite, and Mailpit volumes.
|
||||
|
||||
After this, the next prototype start will recreate empty local backing services.
|
||||
EOF
|
||||
;;
|
||||
5)
|
||||
cat <<EOF
|
||||
|
||||
${BOLD}You selected: Safe global prune${NC}
|
||||
|
||||
This will:
|
||||
- Remove all stopped Docker containers.
|
||||
- Remove unused Docker networks.
|
||||
- Remove dangling image layers.
|
||||
- Remove unused Docker build cache.
|
||||
- Keep named volumes.
|
||||
- Keep images that are still tagged or used by containers.
|
||||
|
||||
After this, Docker should use less disk space while preserving volumes.
|
||||
EOF
|
||||
;;
|
||||
6)
|
||||
cat <<EOF
|
||||
|
||||
${BOLD}You selected: Deeper image/cache prune${NC}
|
||||
|
||||
This will:
|
||||
- Remove all unused Docker images, not just dangling layers.
|
||||
- Remove all unused Docker build cache.
|
||||
- Keep images used by existing containers.
|
||||
- Keep named volumes.
|
||||
|
||||
After this, future builds and starts may need to pull or rebuild images.
|
||||
EOF
|
||||
;;
|
||||
7)
|
||||
cat <<EOF
|
||||
|
||||
${BOLD}You selected: Full global Docker prune${NC}
|
||||
|
||||
This will:
|
||||
- Remove stopped containers across Docker.
|
||||
- Remove unused networks across Docker.
|
||||
- Remove all unused images.
|
||||
- Remove build cache.
|
||||
- Remove all unused volumes, including volumes from other projects if Docker considers them unused.
|
||||
|
||||
After this, Docker disk usage should drop the most, but other local projects may need to recreate data volumes.
|
||||
EOF
|
||||
;;
|
||||
8)
|
||||
cat <<EOF
|
||||
|
||||
${BOLD}You selected: Builder cache only${NC}
|
||||
|
||||
This will:
|
||||
- Remove Docker build cache.
|
||||
- Keep containers, images, networks, and volumes.
|
||||
|
||||
After this, future Docker builds may be slower until the cache is rebuilt.
|
||||
EOF
|
||||
;;
|
||||
q|Q)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
err "Unknown cleanup level: $1"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
run_level() {
|
||||
case "$1" in
|
||||
1) compose_status ;;
|
||||
2) stop_compose ;;
|
||||
3) down_compose ;;
|
||||
4) down_compose_with_volumes ;;
|
||||
5) safe_prune ;;
|
||||
6) unused_image_prune ;;
|
||||
7) full_prune ;;
|
||||
8) builder_prune ;;
|
||||
q|Q) exit 0 ;;
|
||||
*) err "Unknown cleanup level: $1"; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [[ $# -gt 0 ]]; then
|
||||
warn "This script is interactive and does not accept CLI parameters. Ignoring: $*"
|
||||
fi
|
||||
|
||||
show_menu
|
||||
read -r -p "Select cleanup level: " LEVEL
|
||||
describe_level "${LEVEL:-q}"
|
||||
|
||||
if [[ "${LEVEL:-q}" == "1" ]]; then
|
||||
echo ""
|
||||
require_docker
|
||||
run_level "$LEVEL"
|
||||
ok "Done."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if ! confirm "Proceed with this cleanup?"; then
|
||||
warn "Cancelled. No cleanup was performed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
require_docker
|
||||
run_level "${LEVEL:-q}"
|
||||
ok "Done."
|
||||
Loading…
Reference in New Issue
Block a user