← Back to Skills
DevOps

backup

jordanprater By jordanprater 👁 56 views ▲ 0 votes

Backup and restore openclaw configuration, skills, commands, and settings.

GitHub
---
name: backup
description: Backup and restore openclaw configuration, skills, commands, and settings. Sync across devices, version control with git, automate backups, and migrate to new machines.
metadata: {"openclaw":{"emoji":"πŸ’Ύ","requires":{"bins":["git","tar","rsync"],"env":[]}}}
---

# OpenClaw Backup Skill

Backup, restore, and sync your OpenClaw configuration across devices directly from openclaw.

## Overview

This skill helps you:
- Backup all openclaw data and settings
- Restore from backups
- Sync between multiple machines
- Version control your configuration
- Automate backup routines
- Migrate to new devices

## openclaw Directory Structure

### Key Locations

```
~/.claude/                    # Main openclaw directory
β”œβ”€β”€ settings.json             # Global settings
β”œβ”€β”€ settings.local.json       # Local overrides (machine-specific)
β”œβ”€β”€ projects.json             # Project configurations
β”œβ”€β”€ skills/                   # Your custom skills
β”‚   β”œβ”€β”€ skill-name/
β”‚   β”‚   β”œβ”€β”€ SKILL.md
β”‚   β”‚   └── supporting-files/
β”‚   └── another-skill/
β”œβ”€β”€ commands/                 # Custom slash commands (legacy)
β”‚   └── command-name.md
β”œβ”€β”€ contexts/                 # Saved contexts
β”œβ”€β”€ templates/                # Response templates
└── mcp/                      # MCP server configurations
    └── servers.json

~/projects/                   # Your projects (optional backup)
β”œβ”€β”€ project-1/
β”‚   └── .claude/              # Project-specific config
β”‚       β”œβ”€β”€ settings.json
β”‚       └── skills/
└── project-2/
```

### What to Backup

```
ESSENTIAL (Always backup):
βœ“ ~/.claude/skills/           # Custom skills
βœ“ ~/.claude/commands/         # Custom commands
βœ“ ~/.claude/settings.json     # Global settings
βœ“ ~/.claude/mcp/              # MCP configurations

RECOMMENDED (Usually backup):
βœ“ ~/.claude/contexts/         # Saved contexts
βœ“ ~/.claude/templates/        # Templates
βœ“ Project .claude/ folders    # Project configs

OPTIONAL (Case by case):
β—‹ ~/.claude/settings.local.json  # Machine-specific
β—‹ Cache directories              # Can be rebuilt
β—‹ Log files                      # Usually not needed
```

## Quick Backup Commands

### Full Backup

```bash
# Create timestamped backup
BACKUP_DIR="$HOME/openclaw-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="openclaw_backup_$TIMESTAMP"

mkdir -p "$BACKUP_DIR"

tar -czvf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" \
  -C "$HOME" \
  .claude/skills \
  .claude/commands \
  .claude/settings.json \
  .claude/mcp \
  .claude/contexts \
  .claude/templates \
  2>/dev/null

echo "Backup created: $BACKUP_DIR/$BACKUP_NAME.tar.gz"
```

### Quick Skills-Only Backup

```bash
# Backup just skills
tar -czvf ~/openclaw_skills_$(date +%Y%m%d).tar.gz \
  -C "$HOME" .claude/skills .claude/commands
```

### Restore from Backup

```bash
# Restore full backup
BACKUP_FILE="$HOME/openclaw-backups/openclaw_backup_20260129.tar.gz"

# Preview contents first
tar -tzvf "$BACKUP_FILE"

# Restore (will overwrite existing)
tar -xzvf "$BACKUP_FILE" -C "$HOME"

echo "Restore complete!"
```

## Backup Script

### Full-Featured Backup Script

```bash
#!/bin/bash
# openclaw-backup.sh - Comprehensive openclaw backup tool

set -e

# Configuration
BACKUP_ROOT="${openclaw_BACKUP_DIR:-$HOME/openclaw-backups}"
CLAUDE_DIR="$HOME/.claude"
MAX_BACKUPS=10  # Keep last N backups
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# Check if openclaw directory exists
check_claude_dir() {
    if [ ! -d "$CLAUDE_DIR" ]; then
        log_error "openclaw directory not found: $CLAUDE_DIR"
        exit 1
    fi
}

# Create backup
create_backup() {
    local backup_type="${1:-full}"
    local backup_name="openclaw_${backup_type}_${TIMESTAMP}"
    local backup_path="$BACKUP_ROOT/$backup_name.tar.gz"
    
    mkdir -p "$BACKUP_ROOT"
    
    log_info "Creating $backup_type backup..."
    
    case $backup_type in
        full)
            tar -czvf "$backup_path" \
                -C "$HOME" \
                .claude/skills \
                .claude/commands \
                .claude/settings.json \
                .claude/settings.local.json \
                .claude/projects.json \
                .claude/mcp \
                .claude/contexts \
                .claude/templates \
                2>/dev/null || true
            ;;
        skills)
            tar -czvf "$backup_path" \
                -C "$HOME" \
                .claude/skills \
                .claude/commands \
                2>/dev/null || true
            ;;
        settings)
            tar -czvf "$backup_path" \
                -C "$HOME" \
                .claude/settings.json \
                .claude/settings.local.json \
                .claude/mcp \
                2>/dev/null || true
            ;;
        *)
            log_error "Unknown backup type: $backup_type"
            exit 1
            ;;
    esac
    
    if [ -f "$backup_path" ]; then
        local size=$(du -h "$backup_path" | cut -f1)
        log_info "Backup created: $backup_path ($size)"
    else
        log_error "Backup failed!"
        exit 1
    fi
}

# List backups
list_backups() {
    log_info "Available backups in $BACKUP_ROOT:"
    echo ""
    
    if [ -d "$BACKUP_ROOT" ]; then
        ls -lh "$BACKUP_ROOT"/*.tar.gz 2>/dev/null | \
            awk '{print $9, $5, $6, $7, $8}' || \
            echo "No backups found."
    else
        echo "Backup directory doesn't exist."
    fi
}

# Restore backup
restore_backup() {
    local backup_file="$1"
    
    if [ -z "$backup_file" ]; then
        log_error "Please specify backup file"
        list_backups
        exit 1
    fi
    
    if [ ! -f "$backup_file" ]; then
        # Try relative path in backup dir
        backup_file="$BACKUP_ROOT/$backup_file"
    fi
    
    if [ ! -f "$backup_file" ]; then
        log_error "Backup file not found: $backup_file"
        exit 1
    fi
    
    log_warn "This will overwrite existing configuration!"
    read -p "Continue? (y/N) " confirm
    
    if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
        log_info "Restore cancelled."
        exit 0
    fi
    
    log_info "Restoring from: $backup_file"
    tar -xzvf "$backup_file" -C "$HOME"
    log_info "Restore complete!"
}

# Clean old backups
cleanup_backups() {
    log_info "Cleaning old backups (keeping last $MAX_BACKUPS)..."
    
    cd "$BACKUP_ROOT" 2>/dev/null || return
    
    local count=$(ls -1 *.tar.gz 2>/dev/null | wc -l)
    
    if [ "$count" -gt "$MAX_BACKUPS" ]; then
        local to_delete=$((count - MAX_BACKUPS))
        ls -1t *.tar.gz | tail -n "$to_delete" | xargs rm -v
        log_info "Removed $to_delete old backup(s)"
    else
        log_info "No cleanup needed ($count backups)"
    fi
}

# Show backup stats
show_stats() {
    log_info "openclaw Backup Statistics"
    echo ""
    
    echo "=== Directory Sizes ==="
    du -sh "$CLAUDE_DIR"/skills 2>/dev/null || echo "Skills: N/A"
    du -sh "$CLAUDE_DIR"/commands 2>/dev/null || echo "Commands: N/A"
    du -sh "$CLAUDE_DIR"/mcp 2>/dev/null || echo "MCP: N/A"
    du -sh "$CLAUDE_DIR" 2>/dev/null || echo "Total: N/A"
    
    echo ""
    echo "=== Skills Count ==="
    find "$CLAUDE_DIR/skills" -name "SKILL.md" 2>/dev/null | wc -l | xargs echo "Skills:"
    find "$CLAUDE_DIR/commands" -name "*.md" 2>/dev/null | wc -l | xargs echo "Commands:"
    
    echo ""
    echo "=== Backup Directory ==="
    if [ -d "$BACKUP_ROOT" ]; then
        du -sh "$BACKUP_ROOT"
        ls -1 "$BACKUP_ROOT"/*.tar.gz 2>/dev/null | wc -l | xargs echo "Backup files:"
    else
        echo "No backups yet"
    fi
}

# Usage
usage() {
    cat << EOF
openclaw Backup Tool

Usage: $(basename $0) <command> [options]

Commands:
    backup [type]   Create backup (types: full, skills, settings)
    restore <file>  Restore from backup file
    list            List available backups
    cleanup         Remove old backups (keep last $MAX_BACKUPS)
    stats           Show backup statistics
    help            Show this help

Examples:
    $(basename $0) backup              # Full backup
    $(basename $0) backup skills       # Skills only
    $(basename $0) restore latest.tar.gz
    $(basename $0) list
    $(basename $0) cleanup

Environment:
    openclaw_BACKUP_DIR    Backup directory (default: ~/openclaw-backups)

EOF
}

# Main
main() {
    check_claude_dir
    
    case "${1:-help}" in
        backup)
            create_backup "${2:-full}"
            ;;
        restore)
            restore_backup "$2"
            ;;
        list)
            list_backups
            ;;
        cleanup)
            cleanup_backups
            ;;
        stats)
            show_stats
            ;;
        help|--help|-h)
            usage
            ;;
        *)
            log_error "Unknown command: $1"
            usage
            exit 1
            ;;
    esac
}

main "$@"
```

### Save and Use

```bash
# Save script
cat > ~/.local/bin/openclaw-backup << 'SCRIPT'
# Paste script content here
SCRIPT

chmod +x ~/.local/bin/openclaw-backup

# Usage
openclaw-backup backup          # Full backup
openclaw-backup backup skills   # Skills only
openclaw-backup list            # List backups
openclaw-backup restore <file>  # Restore
```

## Git Version Control

### Initialize Git Repo

```bash
cd ~/.claude

# Initialize git
git init

# Create .gitignore
cat > .gitignore << 'EOF'
# Machine-specific settings
settings.local.json

# Cache and temp files
cache/
*.tmp
*.log

# Large files
*.tar.gz
*.zip

# Sensitive data (if any)
*.pem
*.key
credentials/
EOF

# Initial commit
git add .
git commit -m "Initial openclaw configuration backup"
```

### Push to Remote

```bash
# Add remote (GitHub, GitLab, etc)
git remote add origin [email protected]:username/openclaw-config.git

# Push
git push -u origin main
```

### Daily

... (truncated)
devops

Comments

Sign in to leave a comment

Loading comments...