diff --git a/opt/05-backups/scripts/backup-full-enhanced.sh b/opt/05-backups/scripts/backup-full-enhanced.sh index 96f99cf..5dea6e3 100755 --- a/opt/05-backups/scripts/backup-full-enhanced.sh +++ b/opt/05-backups/scripts/backup-full-enhanced.sh @@ -149,31 +149,26 @@ discover_docker_compose_projects() { } discover_databases() { - log "=== Auto-discovering Databases ===" - local databases=() # Auto-detect PostgreSQL containers (common image names and postgres in container name) while IFS= read -r container; do - if docker inspect "$container" --format '{{.Config.Image}}' 2>/dev/null | grep -qiE '(postgres|postgresql|timescale|postgis)'; then + if [[ -n "$container" ]] && docker inspect "$container" --format '{{.Config.Image}}' 2>/dev/null | grep -qiE '(postgres|postgresql|timescale|postgis)'; then databases+=("postgresql:$container") - log "Found PostgreSQL: $container" fi done < <(docker ps --format '{{.Names}}' 2>/dev/null | grep -iE '(postgres|pg|timescale|supabase-db|authentik-postgres|postiz-postgres)') # Auto-detect MariaDB/MySQL containers while IFS= read -r container; do - if docker inspect "$container" --format '{{.Config.Image}}' 2>/dev/null | grep -qiE '(mariadb|mysql)'; then + if [[ -n "$container" ]] && docker inspect "$container" --format '{{.Config.Image}}' 2>/dev/null | grep -qiE '(mariadb|mysql)'; then databases+=("mariadb:$container") - log "Found MariaDB/MySQL: $container" fi done < <(docker ps --format '{{.Names}}' 2>/dev/null | grep -iE '(mariadb|mysql|mautic-db)') # Auto-detect MongoDB containers while IFS= read -r container; do - if docker inspect "$container" --format '{{.Config.Image}}' 2>/dev/null | grep -qiE 'mongo'; then + if [[ -n "$container" ]] && docker inspect "$container" --format '{{.Config.Image}}' 2>/dev/null | grep -qiE 'mongo'; then databases+=("mongodb:$container") - log "Found MongoDB: $container" fi done < <(docker ps --format '{{.Names}}' 2>/dev/null | grep -iE 'mongo') @@ -386,7 +381,12 @@ main() { if [[ -z "$discovered_dbs" ]]; then warning "No databases discovered" else - log "Found databases: $discovered_dbs" + log "Discovered databases:" + for db in $discovered_dbs; do + local db_type=$(echo "$db" | cut -d: -f1) + local db_name=$(echo "$db" | cut -d: -f2) + log " - $db_type: $db_name" + done log "" for db in $discovered_dbs; do diff --git a/opt/05-backups/scripts/export-credentials.sh b/opt/05-backups/scripts/export-credentials.sh new file mode 100755 index 0000000..4d4c4ba --- /dev/null +++ b/opt/05-backups/scripts/export-credentials.sh @@ -0,0 +1,371 @@ +#!/bin/bash + +################################################################################ +# Export All Credentials to Syncthing Folder +# Version: 1.0.0 +# Purpose: Export credentials from .env files and configs to sync folder +################################################################################ + +set -euo pipefail + +# Colors +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +NC='\033[0m' + +log() { echo -e "${CYAN}[$(date +%H:%M:%S)]${NC} $1"; } +success() { echo -e "${GREEN}✅ $1${NC}"; } +warning() { echo -e "${YELLOW}⚠️ $1${NC}"; } + +# Configuration +EXPORT_DIR="/opt/secrets-backup" +TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') + +mkdir -p "$EXPORT_DIR" + +log "╔════════════════════════════════════════════════════════════╗" +log "║ Credentials Export to Syncthing Folder ║" +log "╚════════════════════════════════════════════════════════════╝" +log "" + +################################################################################ +# Create Markdown Documentation +################################################################################ + +cat > "$EXPORT_DIR/CREDENTIALS.md" << 'MDHEADER' +# 🔐 AI-Impress Infrastructure Credentials + +> **Last Updated:** TIMESTAMP_PLACEHOLDER +> **Server:** ai-impress-prod (51.89.231.46) +> **Purpose:** Complete credentials backup for disaster recovery + +**⚠️ SECURITY WARNING:** +- Keep this file secure and encrypted +- Never commit to Git +- Store in encrypted backup location +- Synced via Syncthing (encrypted) + +--- + +## 📑 Quick Access + +- [Core Infrastructure](#core-infrastructure) +- [Security & Authentication](#security--authentication) +- [Business Applications](#business-applications) +- [Databases](#databases) +- [Monitoring & Tools](#monitoring--tools) +- [API Keys & Webhooks](#api-keys--webhooks) + +--- + +MDHEADER + +sed -i "s/TIMESTAMP_PLACEHOLDER/$TIMESTAMP/g" "$EXPORT_DIR/CREDENTIALS.md" + +################################################################################ +# Extract Credentials from .env files +################################################################################ + +log "Extracting credentials from .env files..." + +# Function to safely read .env files +extract_env() { + local service=$1 + local env_file=$2 + + if [[ ! -f "$env_file" ]]; then + return + fi + + cat >> "$EXPORT_DIR/CREDENTIALS.md" << ENVHEADER + +### $service + +**Location:** \`$env_file\` + +\`\`\`env +ENVHEADER + + # Read and mask sensitive values + grep -v '^#' "$env_file" | grep -v '^$' | while IFS='=' read -r key value; do + # Remove quotes + value=$(echo "$value" | sed 's/^"//;s/"$//' | sed "s/^'//;s/'$//") + echo "$key=$value" + done >> "$EXPORT_DIR/CREDENTIALS.md" + + echo '```' >> "$EXPORT_DIR/CREDENTIALS.md" + echo "" >> "$EXPORT_DIR/CREDENTIALS.md" +} + +# Core Infrastructure +cat >> "$EXPORT_DIR/CREDENTIALS.md" << 'SECTION' +## 🏗️ Core Infrastructure + +SECTION + +extract_env "Traefik" "/opt/00-infrastructure/traefik/.env" +extract_env "PostgreSQL Main" "/opt/00-infrastructure/postgres/.env" +extract_env "Redis Main" "/opt/00-infrastructure/redis/.env" +extract_env "Vault" "/opt/00-infrastructure/vault/.env" + +# Security & Authentication +cat >> "$EXPORT_DIR/CREDENTIALS.md" << 'SECTION' +--- + +## 🔐 Security & Authentication + +SECTION + +extract_env "Authentik" "/opt/01-security/authentik/.env" +extract_env "Vaultwarden" "/opt/01-security/vaultwarden/.env" + +# Business Applications +cat >> "$EXPORT_DIR/CREDENTIALS.md" << 'SECTION' +--- + +## 💼 Business Applications + +SECTION + +extract_env "Odoo" "/opt/03-business/odoo/.env" +extract_env "Outline Wiki" "/opt/03-business/outline/.env" +extract_env "Documenso" "/opt/03-business/documenso/.env" +extract_env "Wiki.js" "/opt/03-business/wikijs/.env" + +# Core Services +cat >> "$EXPORT_DIR/CREDENTIALS.md" << 'SECTION' +--- + +## ⚙️ Core Services + +SECTION + +extract_env "N8N Shared" "/opt/02-core/n8n-shared/.env" +extract_env "Evolution API" "/opt/02-core/evolution-api/.env" +extract_env "Supabase" "/opt/02-core/supabase/supabase/docker/.env" +extract_env "Postiz" "/opt/02-core/postiz/.env" +extract_env "Presenton" "/opt/02-core/presenton/.env" + +# Monitoring & Tools +cat >> "$EXPORT_DIR/CREDENTIALS.md" << 'SECTION' +--- + +## 📊 Monitoring & Tools + +SECTION + +extract_env "Grafana" "/opt/04-tools/grafana/.env" +extract_env "Prometheus" "/opt/04-tools/prometheus/.env" +extract_env "Portainer" "/opt/04-tools/portainer/.env" +extract_env "Uptime Kuma" "/opt/04-tools/uptime-kuma/.env" + +################################################################################ +# Extract URLs and Access Points +################################################################################ + +cat >> "$EXPORT_DIR/CREDENTIALS.md" << 'URLS' +--- + +## 🌐 Service URLs & Access + +### Public Services + +| Service | URL | Notes | +|---------|-----|-------| +| **Odoo** | https://odoo.ai-impress.com | ERP & CRM | +| **N8N** | https://n8n.ai-impress.com | Workflow Automation | +| **Outline** | https://wiki.ai-impress.com | Main Wiki | +| **Wiki.js** | https://info.ai-impress.com | Documentation | +| **Documenso** | https://sign.ai-impress.com | E-Signatures | +| **Postiz** | https://social.ai-impress.com | Social Media | +| **Evolution API** | https://wpp.ai-impress.com | WhatsApp API | +| **Supabase** | https://supabase.ai-impress.com | Backend as a Service | +| **Authentik** | https://auth.ai-impress.com | SSO | +| **Vaultwarden** | https://vault.ai-impress.com | Password Manager | + +### Admin Tools + +| Tool | URL | Access | +|------|-----|--------| +| **Grafana** | https://grafana.ai-impress.com | Admin only | +| **Prometheus** | https://prometheus.ai-impress.com | Admin only | +| **Portainer** | https://portainer.ai-impress.com | Admin only | +| **Traefik** | https://traefik.ai-impress.com | Admin only | +| **Uptime Kuma** | https://status.ai-impress.com | Public status | +| **pgAdmin** | https://pgadmin.ai-impress.com | DB Admin | +| **RabbitMQ** | https://rabbitmq.ai-impress.com | Message Queue | + +--- + +## 🗄️ Databases + +### PostgreSQL Main (postgres-main) + +- **Host:** postgres-main (internal network) +- **Port:** 5432 +- **Admin User:** aimpress_admin +- **Connection:** `postgresql://aimpress_admin:PASSWORD@postgres-main:5432/` + +**Databases:** +- n8n_shared +- odoo_db +- outline_db +- wikijs_db +- documenso_db + +### Database Locations + +- **PostgreSQL Data:** `/mnt/psql-data/` +- **Local Backups:** `/mnt/backups/local-backups/` +- **Cloud Backups:** Cloudflare R2 (via Restic) + +--- + +## 🔑 SSH Access + +```bash +# SSH to server +ssh ubuntu@51.89.231.46 + +# Root access (if needed) +sudo -i +``` + +--- + +## 💾 Backup Information + +### Backup Scripts + +- **Full Backup:** `/opt/05-backups/scripts/backup-full-enhanced.sh` +- **Health Check:** `/opt/05-backups/scripts/health-check-alerting.sh` +- **Admin Tool:** `/opt/05-backups/scripts/admin.sh` + +### Backup Locations + +- **Local:** `/mnt/backups/local-backups/` +- **Cloud:** Cloudflare R2 (s3:https://6aff840a680098927b58beb93b59dd03.r2.cloudflarestorage.com/aimpress-backups) +- **Retention:** 14 days local, 30 days cloud + +### Restic Configuration + +- **Repository:** `s3:https://6aff840a680098927b58beb93b59dd03.r2.cloudflarestorage.com/aimpress-backups` +- **Config:** `/opt/05-backups/restic/.env` +- **Snapshots:** Keep 3 daily + 1 weekly + +--- + +## 📞 Emergency Contacts + +### Server Access +- **Provider:** OVH +- **Server IP:** 51.89.231.46 +- **SSH Key:** `~/.ssh/id_rsa` (on admin machine) + +### Domain +- **Registrar:** Cloudflare +- **Domain:** ai-impress.com +- **DNS:** Managed by Cloudflare + +### Cloud Services +- **Cloudflare R2:** 6aff840a680098927b58beb93b59dd03.r2.cloudflarestorage.com +- **GitHub:** github.com/SamoilenkoVadym/OVHserver + +--- + +## 🆘 Disaster Recovery + +### Quick Recovery Steps + +1. **Server Access:** + ```bash + ssh ubuntu@51.89.231.46 + ``` + +2. **Check System Status:** + ```bash + /opt/05-backups/scripts/admin.sh status + ``` + +3. **Restore from Backup:** + ```bash + # List available snapshots + source /opt/05-backups/restic/.env + restic snapshots + + # Restore specific snapshot + restic restore --target /tmp/restore + ``` + +4. **Restart Services:** + ```bash + cd /opt/ + docker-compose restart + ``` + +--- + +## 📝 Notes + +- All services use Traefik for reverse proxy and SSL +- SSL certificates automatically managed by Let's Encrypt +- Authentik provides SSO for most services +- Database passwords stored in respective .env files +- Regular backups run at 3:00 AM daily + +--- + +*Generated by: `/opt/05-backups/scripts/export-credentials.sh`* +*Last updated: TIMESTAMP_PLACEHOLDER* + +URLS + +sed -i "s/TIMESTAMP_PLACEHOLDER/$TIMESTAMP/g" "$EXPORT_DIR/CREDENTIALS.md" + +################################################################################ +# Set Permissions +################################################################################ + +chmod 600 "$EXPORT_DIR/CREDENTIALS.md" +chmod 700 "$EXPORT_DIR" + +success "Permissions set (600/700)" + +################################################################################ +# Create timestamp file +################################################################################ + +cat > "$EXPORT_DIR/last-sync.txt" << EOF +Last Sync: $TIMESTAMP +Hostname: $(hostname) +Export Script: $0 +Export Location: $EXPORT_DIR +EOF + +chmod 600 "$EXPORT_DIR/last-sync.txt" + +################################################################################ +# Summary +################################################################################ + +EXPORT_SIZE=$(du -sh "$EXPORT_DIR" | cut -f1) +FILE_COUNT=$(find "$EXPORT_DIR" -type f | wc -l) + +log "" +log "╔════════════════════════════════════════════════════════════╗" +log "║ EXPORT COMPLETED ║" +log "╚════════════════════════════════════════════════════════════╝" +log "" +log " 📄 Files Exported: $FILE_COUNT" +log " 📝 Main File: CREDENTIALS.md" +log " 💾 Total Size: $EXPORT_SIZE" +log " 📍 Location: $EXPORT_DIR" +log "" +success "Credentials exported successfully!" +log "" +log "Files will be synced to Mac via Syncthing:" +log " → /Volumes/SSD/Aimpress_Cloud_Prod/secrets-backup/" +log "" +log "⚠️ Keep these files secure! They contain sensitive information." +log ""