#!/usr/bin/env bash # ============================================================================= # Changemaker Lite — Uninstall Script # # Safely stops and removes all Changemaker containers, volumes, and files. # Handles root-owned files created by Docker containers. # # Usage: # bash scripts/uninstall.sh [OPTIONS] # # Options: # --keep-data Keep database volumes (PostgreSQL, Redis, etc.) # --keep-media Keep the media/ directory (uploaded files) # --yes, -y Skip confirmation prompt # --help Show this help # ============================================================================= set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" KEEP_DATA=false KEEP_MEDIA=false SKIP_CONFIRM=false # Colors if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' BOLD='\033[1m' NC='\033[0m' else RED='' GREEN='' YELLOW='' BLUE='' BOLD='' NC='' fi info() { echo -e "${BLUE}[INFO]${NC} $*"; } success() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } while [[ $# -gt 0 ]]; do case "$1" in --keep-data) KEEP_DATA=true; shift ;; --keep-media) KEEP_MEDIA=true; shift ;; --yes|-y) SKIP_CONFIRM=true; shift ;; --help|-h) sed -n '2,16p' "$0" | grep '^#' | sed 's/^# \?//' exit 0 ;; *) shift ;; esac done echo -e "${BOLD}Changemaker Lite — Uninstall${NC}" echo "" if [[ ! -f "$SCRIPT_DIR/docker-compose.yml" ]]; then error "Not a Changemaker Lite installation: $SCRIPT_DIR" exit 1 fi info "Install directory: $SCRIPT_DIR" [[ "$KEEP_DATA" == "true" ]] && info "Database volumes will be preserved" [[ "$KEEP_MEDIA" == "true" ]] && info "Media files will be preserved" echo "" if [[ "$SKIP_CONFIRM" == "false" ]]; then echo -e "${RED}${BOLD}WARNING: This will permanently remove Changemaker Lite.${NC}" read -rp "Type 'uninstall' to confirm: " confirm if [[ "$confirm" != "uninstall" ]]; then echo "Cancelled." exit 0 fi fi # Step 1: Stop and remove containers echo "" info "Stopping containers..." cd "$SCRIPT_DIR" if [[ "$KEEP_DATA" == "true" ]]; then docker compose down --remove-orphans 2>/dev/null || true else docker compose down -v --remove-orphans 2>/dev/null || true fi success "Containers stopped" # Step 2: Remove systemd units (if installed) if command -v systemctl &>/dev/null; then for unit in changemaker-upgrade.path changemaker-upgrade.service changemaker-backup.timer changemaker-backup.service; do if systemctl is-enabled "$unit" &>/dev/null 2>&1; then info "Removing systemd unit: $unit" sudo systemctl disable --now "$unit" 2>/dev/null || true sudo rm -f "/etc/systemd/system/$unit" 2>/dev/null || true fi done sudo systemctl daemon-reload 2>/dev/null || true fi # Step 3: Remove files info "Removing installation files..." # Try normal rm first cd "$HOME" if [[ "$KEEP_MEDIA" == "true" ]]; then # Move media out, remove everything, move media back MEDIA_TMP=$(mktemp -d) mv "$SCRIPT_DIR/media" "$MEDIA_TMP/" 2>/dev/null || true fi rm -rf "$SCRIPT_DIR" 2>/dev/null || true # Handle root-owned files from Docker if [[ -d "$SCRIPT_DIR" ]]; then warn "Some files are root-owned (from Docker). Using sudo to clean up..." sudo rm -rf "$SCRIPT_DIR" 2>/dev/null || { error "Could not remove $SCRIPT_DIR — manual cleanup needed:" echo " sudo rm -rf $SCRIPT_DIR" } fi # Restore media if requested if [[ "$KEEP_MEDIA" == "true" ]] && [[ -d "${MEDIA_TMP:-}/media" ]]; then mkdir -p "$SCRIPT_DIR" mv "$MEDIA_TMP/media" "$SCRIPT_DIR/" rm -rf "$MEDIA_TMP" success "Media files preserved at $SCRIPT_DIR/media/" fi echo "" success "Changemaker Lite has been uninstalled." [[ "$KEEP_DATA" == "true" ]] && info "Database volumes were preserved (use 'docker volume ls' to manage)" echo ""