{"id":28758559,"url":"https://github.com/drhdev/supabase-backup","last_synced_at":"2025-06-17T04:08:54.205Z","repository":{"id":298124907,"uuid":"998948124","full_name":"drhdev/supabase-backup","owner":"drhdev","description":"A shellscript for backing up Supabase self-hosted using Restic and rclone.","archived":false,"fork":false,"pushed_at":"2025-06-09T14:05:08.000Z","size":27,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-09T15:20:39.636Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drhdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-09T14:01:11.000Z","updated_at":"2025-06-09T14:05:11.000Z","dependencies_parsed_at":"2025-06-09T15:32:28.690Z","dependency_job_id":null,"html_url":"https://github.com/drhdev/supabase-backup","commit_stats":null,"previous_names":["drhdev/supabase-backup"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/drhdev/supabase-backup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drhdev%2Fsupabase-backup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drhdev%2Fsupabase-backup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drhdev%2Fsupabase-backup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drhdev%2Fsupabase-backup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drhdev","download_url":"https://codeload.github.com/drhdev/supabase-backup/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drhdev%2Fsupabase-backup/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260288446,"owners_count":22986668,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-17T04:08:53.423Z","updated_at":"2025-06-17T04:08:54.185Z","avatar_url":"https://github.com/drhdev.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Supabase Backup with Restic\n\nThis repository contains a comprehensive backup solution for Supabase self-hosted instances, using Restic for encrypted backups. It's designed to work with the [supabase-automated-self-host](https://github.com/singh-inder/supabase-automated-self-host/) repository.\n\n## Features\n\n- PostgreSQL database dumps\n- Configuration backup (.env, Caddy, Authelia, Docker Compose)\n- MinIO bucket backup via rclone\n- Encrypted backup to multiple storage providers:\n  - DigitalOcean Spaces\n  - Amazon S3\n  - Hetzner Object Storage (S3-compatible with limitations)\n- Automatic retention policy\n- Clean logging\n\n## Prerequisites\n\n### Required Software\n- Docker and Docker Compose (required for Supabase self-hosted setup)\n- Restic (latest version)\n- Rclone (latest version)\n- Git\n\n### Software Installation\n\n#### Restic Installation (Ubuntu 22.04)\n```bash\n# Add Restic repository\ncurl -fsSL https://apt.restic.net/restic.gpg | sudo gpg --dearmor -o /usr/share/keyrings/restic-archive-keyring.gpg\necho \"deb [signed-by=/usr/share/keyrings/restic-archive-keyring.gpg] https://apt.restic.net/ $(lsb_release -cs) main\" | sudo tee /etc/apt/sources.list.d/restic.list\n\n# Update package list and install Restic\nsudo apt update\nsudo apt install restic\n```\n\n#### Rclone Installation (Ubuntu 22.04)\n```bash\n# Check if Rclone is already installed\nif command -v rclone \u0026\u003e /dev/null; then\n    echo \"Rclone is already installed. Current version:\"\n    rclone version\n    echo \"To update to the latest version, run:\"\n    echo \"curl https://rclone.org/install.sh | sudo bash\"\nelse\n    # Download and install Rclone\n    curl https://rclone.org/install.sh | sudo bash\nfi\n\n# Create Rclone config directory if it doesn't exist\nmkdir -p ~/.config/rclone\n```\n\n### Required Accounts\n- One of the following storage providers:\n  - DigitalOcean Spaces account\n  - Amazon S3 account\n  - Hetzner Object Storage account\n- MinIO instance (part of Supabase self-hosted setup)\n\n### Required Information\n- Storage provider credentials\n- MinIO access and secret keys\n- Supabase database credentials\n- Strong password for Restic encryption\n\n## Installation\n\n1. Clone this repository:\n   ```bash\n   git clone https://github.com/yourusername/supabase-backup.git\n   cd supabase-backup\n   ```\n\n2. Create the backup directory and set permissions:\n   ```bash\n   # Create directory with proper ownership\n   sudo mkdir -p /opt/supabase-backups\n   sudo cp supabase_backup_restic.sh /opt/supabase-backups/\n   sudo chown -R $USER:$USER /opt/supabase-backups\n   sudo chmod +x /opt/supabase-backups/supabase_backup_restic.sh\n   ```\n\n3. Configure restic:\n   ```bash\n   cp restic.env.example /opt/supabase-backups/restic.env\n   chmod 600 /opt/supabase-backups/restic.env  # Restrict permissions to owner only\n   # Edit restic.env with your storage provider credentials\n   ```\n\n4. Configure rclone:\n   ```bash\n   mkdir -p ~/.config/rclone\n   cp rclone.conf.example ~/.config/rclone/rclone.conf\n   chmod 600 ~/.config/rclone/rclone.conf  # Restrict permissions to owner only\n   # Edit rclone.conf with your MinIO credentials\n   ```\n\n## Storage Provider Setup\n\n### Storage Provider Comparison\n\n| Provider | Encryption Type | Additional Requirements |\n|:---------|:---------------|:----------------------|\n| DigitalOcean Spaces | S3 Default | None |\n| Amazon S3 | S3 Default | None |\n| Hetzner Object Storage | SSE-C Only | Requires SSE-C key management |\n\n### 1. DigitalOcean Spaces\n1. Create a Space in your DigitalOcean account\n2. Generate API keys (Access Key and Secret Key)\n3. In `restic.env`:\n   ```bash\n   RESTIC_REPOSITORY=s3:https://fra1.digitaloceanspaces.com/your-space-name\n   AWS_ACCESS_KEY_ID=your_access_key\n   AWS_SECRET_ACCESS_KEY=your_secret_key\n   ```\n\n### 2. Amazon S3\n1. Create an S3 bucket in your AWS account\n2. Create an IAM user with S3 access\n3. Generate access keys for the IAM user\n4. In `restic.env`:\n   ```bash\n   RESTIC_REPOSITORY=s3:s3.amazonaws.com/your-bucket-name\n   AWS_ACCESS_KEY_ID=your_access_key\n   AWS_SECRET_ACCESS_KEY=your_secret_key\n   ```\n\n### 3. Hetzner Object Storage\n1. Create a bucket in Hetzner Object Storage\n2. Generate access keys in the Hetzner Cloud Console\n3. Important limitations to be aware of:\n   - Only SSE-C encryption is supported (different from other providers)\n   - No support for Request-Payment, Notifications, Accelerate, Website, Analytics\n   - No support for Intelligent Tiering, Inventory, Logging, Metrics\n   - No support for Ownership Controls, Replication, Tagging\n   - No support for custom domains for buckets\n4. Generate SSE-C key (Hetzner-specific requirement):\n   ```bash\n   # Generate a 32-byte (256-bit) key and encode it in base64\n   openssl rand -base64 32 \u003e /opt/supabase-backups/sse-c-key.txt\n   # Set proper permissions\n   chmod 600 /opt/supabase-backups/sse-c-key.txt\n   ```\n   Store this key securely - you'll need it for both backup and restore operations.\n5. In `restic.env`:\n   ```bash\n   RESTIC_REPOSITORY=s3:https://eu-central-1.hetzner.com/your-bucket-name\n   AWS_ACCESS_KEY_ID=your-hetzner-access-key\n   AWS_SECRET_ACCESS_KEY=your-hetzner-secret-key\n   RESTIC_S3_SSE_C_KEY=$(cat /opt/supabase-backups/sse-c-key.txt)  # Hetzner-specific requirement\n   ```\n\n### Hetzner SSE-C Key Management (Hetzner-specific)\n\nThe SSE-C (Server-Side Encryption with Customer-Provided Keys) key is required only for Hetzner Object Storage. Other providers (DigitalOcean Spaces and Amazon S3) use their own encryption methods and don't require this key.\n\n1. Key Generation:\n   - Always use a cryptographically secure random generator (like OpenSSL)\n   - The key must be 32 bytes (256 bits) for AES-256 encryption\n   - Base64 encoding is required for the key format\n\n2. Key Storage:\n   - Store the key in a secure location with restricted permissions (600)\n   - Consider using a key management service for production environments\n   - Never commit the key to version control\n   - Keep a secure backup of the key - if lost, you cannot decrypt your backups\n\n3. Key Rotation:\n   - While Hetzner doesn't require key rotation, it's a good security practice\n   - To rotate keys:\n     ```bash\n     # Generate new key\n     openssl rand -base64 32 \u003e /opt/supabase-backups/sse-c-key-new.txt\n     chmod 600 /opt/supabase-backups/sse-c-key-new.txt\n     \n     # Create new backup with new key\n     export RESTIC_S3_SSE_C_KEY=$(cat /opt/supabase-backups/sse-c-key-new.txt)\n     restic backup /path/to/data\n     \n     # Verify backup is accessible with new key\n     restic snapshots\n     \n     # If successful, replace old key\n     mv /opt/supabase-backups/sse-c-key-new.txt /opt/supabase-backups/sse-c-key.txt\n     ```\n\n4. Disaster Recovery:\n   - Document the key generation process\n   - Store the key in a secure, accessible location\n   - Consider using a password manager or secure vault\n   - Test restore procedures regularly with the key\n\n5. Security Best Practices:\n   - Use different SSE-C keys for different environments (dev/staging/prod)\n   - Monitor access to the key file\n   - Implement key rotation policies\n   - Document key management procedures\n\n## MinIO Configuration\n\n1. Get your MinIO credentials from your Supabase `.env` file:\n   ```\n   MINIO_ROOT_USER=your_access_key\n   MINIO_ROOT_PASSWORD=your_secret_key\n   ```\n\n2. Configure rclone:\n   ```bash\n   rclone config\n   ```\n   Use these settings:\n   - Type: s3\n   - Provider: Minio\n   - Access Key: Your MinIO access key\n   - Secret Key: Your MinIO secret key\n   - Endpoint: Your MinIO endpoint (usually http://localhost:9000)\n   - Region: us-east-1\n\n## Cronjob Setup\n\nAdd to crontab:\n```bash\n# Edit crontab for current user\ncrontab -e\n```\n\nAdd this line:\n```\n0 3 * * * /opt/supabase-backups/supabase_backup_restic.sh \u003e\u003e /opt/supabase-backups/cron.log 2\u003e\u00261\n```\n\n## Restore Process\n\n1. List available backups:\n   ```bash\n   source /opt/supabase-backups/restic.env\n   restic snapshots\n   ```\n\n2. Restore the latest backup:\n   ```bash\n   restic restore latest --target /tmp/restore\n   ```\n\n3. Restore components:\n   - PostgreSQL: Use the .backup file to restore the database\n   - Configuration: Copy files from /tmp/restore/config to your Supabase directory\n   - MinIO buckets: Use rclone to copy data back to MinIO\n\n## Backup Retention\n\nThe script implements the following retention policy:\n- Daily backups: 7 days\n- Weekly backups: 4 weeks\n- Monthly backups: 6 months\n\n## Logging\n\n- Main backup log: `/opt/supabase-backups/backup.log`\n- Cron job log: `/opt/supabase-backups/cron.log`\n\n## Security Notes\n\n- Keep your `restic.env` file secure and restrict access (chmod 600)\n- Use strong passwords for Restic encryption\n- Regularly rotate your storage provider access keys\n- Monitor backup logs for any issues\n- Store your Restic password securely - it's required for restore operations\n- For Hetzner Object Storage: Keep your SSE-C key secure as it's required for both backup and restore\n- Ensure all configuration files have restricted permissions (chmod 600)\n- Run the backup script as a regular user with sudo privileges, not as root\n\n## Troubleshooting\n\n1. Check backup logs:\n   ```bash\n   tail -f /opt/supabase-backups/backup.log\n   ```\n\n2. Verify rclone configuration:\n   ```bash\n   rclone lsd minio:\n   ```\n\n3. Test restic connection:\n   ```bash\n   source /opt/supabase-backups/restic.env\n   restic snapshots\n   ```\n\n4. Common issues:\n   - Permission denied: Check file permissions and ownership\n   - Connection errors: Verify network connectivity and credentials\n   - Storage full: Check available space in your storage provider\n   - MinIO sync issues: Verify MinIO is running and accessible\n   - Hetzner SSE-C errors: Ensure SSE-C key is properly set and consistent\n\n## License\n\nGNU Public License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrhdev%2Fsupabase-backup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrhdev%2Fsupabase-backup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrhdev%2Fsupabase-backup/lists"}