# Release Notes - v1.3.75 **Release Date:** 2. januar 2026 ## โœจ New Features ### SFTP Offsite Backup - **Implemented SFTP offsite backup** - Backups can now be uploaded to remote SFTP server - **Auto-upload support** - Backups can be automatically uploaded after creation - **Manual upload** - Backups can be manually uploaded via web UI - **Upload verification** - File size verification ensures successful upload - **Retry mechanism** - Failed uploads can be retried with error tracking ### Database Schema Updates - Added `offsite_status` column (pending, uploading, uploaded, failed) - Added `offsite_location` column for remote file path - Added `offsite_attempts` counter for retry tracking - Added `offsite_last_error` for error logging ## ๐Ÿ”ง Technical Improvements ### SFTP Implementation - Uses `paramiko` library for SFTP connections - Supports password authentication - Automatic directory creation on remote server - Progress tracking during upload - Connection timeout protection (30s banner timeout) ### Configuration - `OFFSITE_ENABLED` - Enable/disable offsite uploads - `SFTP_HOST` - Remote SFTP server hostname - `SFTP_PORT` - SFTP port (default: 22) - `SFTP_USER` - SFTP username - `SFTP_PASSWORD` - SFTP password - `SFTP_REMOTE_PATH` - Remote directory path ### Bug Fixes - Fixed infinite loop in `_ensure_remote_directory()` for relative paths - Fixed duplicate `upload_to_offsite()` method - removed redundant code - Fixed router method name mismatch (`upload_offsite` vs `upload_to_offsite`) - Added protection against empty/root path directory creation ## ๐Ÿ“ Files Changed - `app/backups/backend/service.py` - SFTP upload implementation - `app/backups/backend/router.py` - Offsite upload endpoint - `app/backups/templates/index.html` - Frontend offsite upload button - `app/core/config.py` - SFTP configuration settings - `migrations/052_backup_offsite_columns.sql` - Database schema migration - `.env` - SFTP configuration ## ๐Ÿš€ Deployment Instructions ### Prerequisites - Ensure `.env` file contains SFTP credentials - Database migration must be applied ### Production Server Update 1. **SSH til serveren:** ```bash ssh bmcadmin@172.16.31.183 ``` 2. **Naviger til projekt directory:** ```bash cd /opt/bmc_hub # Eller korrekt sti ``` 3. **Pull ny version:** ```bash git fetch --tags git checkout v1.3.75 ``` 4. **Opdater .env fil med SFTP credentials:** ```bash nano .env # Tilfรธj: # OFFSITE_ENABLED=true # SFTP_HOST=sftp.acdu.dk # SFTP_PORT=9022 # SFTP_USER=sftp_bmccrm # SFTP_PASSWORD= # SFTP_REMOTE_PATH=SFTP_BMCCRM ``` 5. **Kรธr database migration:** ```bash docker-compose exec postgres psql -U bmcnetworks -d bmc_hub -f /migrations/052_backup_offsite_columns.sql # ELLER manuel ALTER TABLE: docker-compose exec postgres psql -U bmcnetworks -d bmc_hub -c " ALTER TABLE backup_jobs ADD COLUMN IF NOT EXISTS offsite_status VARCHAR(20) CHECK(offsite_status IN ('pending','uploading','uploaded','failed')); ALTER TABLE backup_jobs ADD COLUMN IF NOT EXISTS offsite_location VARCHAR(500); ALTER TABLE backup_jobs ADD COLUMN IF NOT EXISTS offsite_attempts INTEGER DEFAULT 0; ALTER TABLE backup_jobs ADD COLUMN IF NOT EXISTS offsite_last_error TEXT; " ``` 6. **Genstart containers:** ```bash docker-compose down docker-compose up -d --build ``` 7. **Verificer:** ```bash docker-compose logs -f api | grep -i offsite curl http://localhost:8001/health # Test offsite upload: curl -X POST http://localhost:8001/api/v1/backups/offsite/{job_id} ``` ## ๐Ÿงช Testing ### Verify SFTP Connection ```bash # From inside API container: docker-compose exec api bash apt-get update && apt-get install -y lftp lftp -u sftp_bmccrm,'' sftp://sftp.acdu.dk:9022 -e 'ls SFTP_BMCCRM; quit' ``` ### Test Upload 1. Create a backup via web UI: http://localhost:8001/backups 2. Click "Upload to Offsite" button for the backup 3. Check logs for "โœ… Upload completed" 4. Verify `offsite_uploaded_at` is set in database ## โš ๏ธ Breaking Changes None - this is a feature addition ## ๐Ÿ“Š Database Migration **Migration File:** `migrations/052_backup_offsite_columns.sql` **Impact:** Adds 4 new columns to `backup_jobs` table - Safe to run on existing data (uses ADD COLUMN IF NOT EXISTS) - No data loss risk - Existing backups will have NULL values for new columns ## ๐Ÿ” Security Notes - SFTP password stored in `.env` file (not in repository) - Uses paramiko's `AutoAddPolicy` for host keys - File size verification prevents corrupt uploads - Connection timeout prevents indefinite hangs ## ๐Ÿ“ž Support Ved problemer, kontakt Christian Thomas eller check logs: ```bash docker-compose logs -f api | grep -E "(offsite|SFTP|Upload)" ``` --- **Git Tag:** v1.3.75 **Previous Version:** v1.3.74 **Tested on:** Local development environment (macOS Docker)