235 lines
7.9 KiB
Bash
235 lines
7.9 KiB
Bash
#!/bin/bash
|
|
# Data Migration Script from Synology to Ubuntu Server
|
|
# Run this script after the initial deployment is complete
|
|
|
|
set -e
|
|
|
|
echo "=== Stiftung Data Migration Script ==="
|
|
echo "This script migrates data from Synology NAS to Ubuntu Server"
|
|
|
|
# Check if running as stiftung user
|
|
if [ "$USER" != "stiftung" ]; then
|
|
echo "Error: This script must be run as the 'stiftung' user"
|
|
echo "Run: su - stiftung"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if we're in the right directory
|
|
if [ ! -f "docker-compose.prod.yml" ]; then
|
|
echo "Error: docker-compose.prod.yml not found"
|
|
echo "Make sure you're in the /opt/stiftung directory"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if containers are running
|
|
if ! docker compose -f docker-compose.prod.yml ps | grep -q "Up"; then
|
|
echo "Error: Containers are not running"
|
|
echo "Run: ./deploy.sh first"
|
|
exit 1
|
|
fi
|
|
|
|
echo "=== Step 1: Preparing for Migration ==="
|
|
# Create backup directory
|
|
mkdir -p migration-data
|
|
cd migration-data
|
|
|
|
echo "Please upload your backup files to /opt/stiftung/migration-data/"
|
|
echo "Expected files:"
|
|
echo " - full_backup_YYYYMMDD.json (Django data export)"
|
|
echo " - db_backup_YYYYMMDD.sql (PostgreSQL dump)"
|
|
echo " - media_backup_YYYYMMDD.tar.gz (Media files)"
|
|
echo ""
|
|
echo "Press Enter when files are uploaded..."
|
|
read
|
|
|
|
# Verify backup files exist
|
|
if ! ls full_backup_*.json >/dev/null 2>&1; then
|
|
echo "Error: No Django backup file found (full_backup_*.json)"
|
|
exit 1
|
|
fi
|
|
|
|
if ! ls db_backup_*.sql >/dev/null 2>&1; then
|
|
echo "Error: No database backup file found (db_backup_*.sql)"
|
|
exit 1
|
|
fi
|
|
|
|
if ! ls media_backup_*.tar.gz >/dev/null 2>&1; then
|
|
echo "Error: No media backup file found (media_backup_*.tar.gz)"
|
|
exit 1
|
|
fi
|
|
|
|
echo "✓ All backup files found"
|
|
|
|
echo "=== Step 2: Database Migration ==="
|
|
echo "Choose migration method:"
|
|
echo "1) Load Django JSON backup (recommended for clean migration)"
|
|
echo "2) Restore PostgreSQL dump (faster, but may have compatibility issues)"
|
|
echo "3) Skip database migration"
|
|
read -p "Enter choice (1-3): " migration_choice
|
|
|
|
case $migration_choice in
|
|
1)
|
|
echo "Loading Django JSON backup..."
|
|
# Copy JSON file to container
|
|
JSON_FILE=$(ls full_backup_*.json | head -1)
|
|
docker cp "$JSON_FILE" stiftung-web:/tmp/backup.json
|
|
|
|
# Load data
|
|
echo "This may take several minutes..."
|
|
docker compose -f ../docker-compose.prod.yml exec web python manage.py loaddata /tmp/backup.json
|
|
echo "✓ Django data loaded successfully"
|
|
;;
|
|
2)
|
|
echo "Restoring PostgreSQL dump..."
|
|
SQL_FILE=$(ls db_backup_*.sql | head -1)
|
|
|
|
# Get database credentials from .env
|
|
source ../.env
|
|
|
|
# Drop and recreate database to ensure clean state
|
|
docker compose -f ../docker-compose.prod.yml exec db psql -U postgres -c "DROP DATABASE IF EXISTS $POSTGRES_DB;"
|
|
docker compose -f ../docker-compose.prod.yml exec db psql -U postgres -c "CREATE DATABASE $POSTGRES_DB OWNER $POSTGRES_USER;"
|
|
|
|
# Restore data
|
|
docker cp "$SQL_FILE" stiftung-db:/tmp/backup.sql
|
|
docker compose -f ../docker-compose.prod.yml exec db psql -U $POSTGRES_USER -d $POSTGRES_DB -f /tmp/backup.sql
|
|
|
|
# Run migrations to ensure schema is up to date
|
|
docker compose -f ../docker-compose.prod.yml exec web python manage.py migrate
|
|
echo "✓ PostgreSQL data restored successfully"
|
|
;;
|
|
3)
|
|
echo "Skipping database migration"
|
|
;;
|
|
*)
|
|
echo "Invalid choice, skipping database migration"
|
|
;;
|
|
esac
|
|
|
|
echo "=== Step 3: Media Files Migration ==="
|
|
read -p "Restore media files? (y/n): " restore_media
|
|
|
|
if [[ $restore_media =~ ^[Yy]$ ]]; then
|
|
echo "Restoring media files..."
|
|
MEDIA_FILE=$(ls media_backup_*.tar.gz | head -1)
|
|
|
|
# Extract media files to the correct location
|
|
tar -xzf "$MEDIA_FILE" -C ../app/
|
|
|
|
# Fix permissions
|
|
chown -R stiftung:stiftung ../app/media/
|
|
echo "✓ Media files restored successfully"
|
|
fi
|
|
|
|
echo "=== Step 4: User Account Migration ==="
|
|
echo "Creating superuser account for production..."
|
|
echo "Note: You'll need to create a new superuser account"
|
|
echo "The old passwords won't work due to different SECRET_KEY"
|
|
|
|
read -p "Create new superuser now? (y/n): " create_user
|
|
if [[ $create_user =~ ^[Yy]$ ]]; then
|
|
docker compose -f ../docker-compose.prod.yml exec web python manage.py createsuperuser
|
|
fi
|
|
|
|
echo "=== Step 5: Post-Migration Tasks ==="
|
|
|
|
# Run any additional migrations for new features
|
|
echo "Running migrations for new features..."
|
|
docker compose -f ../docker-compose.prod.yml exec web python manage.py migrate
|
|
|
|
# Rebuild search indexes if needed
|
|
echo "Rebuilding search indexes..."
|
|
docker compose -f ../docker-compose.prod.yml exec web python manage.py shell << 'EOF'
|
|
try:
|
|
from django.core.management import call_command
|
|
call_command('rebuild_index', interactive=False)
|
|
print("Search indexes rebuilt successfully")
|
|
except:
|
|
print("No search indexes to rebuild")
|
|
EOF
|
|
|
|
# Verify HelpBox system
|
|
echo "Verifying HelpBox system..."
|
|
docker compose -f ../docker-compose.prod.yml exec web python manage.py shell << 'EOF'
|
|
from stiftung.models import HelpBox
|
|
count = HelpBox.objects.count()
|
|
print(f"HelpBoxes found: {count}")
|
|
if count == 0:
|
|
print("Creating default help boxes...")
|
|
from django.contrib.auth import get_user_model
|
|
User = get_user_model()
|
|
admin_user = User.objects.filter(is_superuser=True).first()
|
|
|
|
if admin_user:
|
|
help_boxes = [
|
|
('destinataer_new', 'Neuer Destinatär', '## Destinatär erstellen\n\nHier können Sie einen neuen Destinatär anlegen.'),
|
|
('foerderung_new', 'Neue Förderung', '## Förderung erstellen\n\nErstellen Sie hier eine neue Förderung.'),
|
|
('unterstuetzung_new', 'Neue Unterstützung', '## Unterstützung erstellen\n\nLegen Sie eine neue Unterstützung an.'),
|
|
]
|
|
|
|
for page_key, title, content in help_boxes:
|
|
HelpBox.objects.get_or_create(
|
|
page_key=page_key,
|
|
defaults={
|
|
'title': title,
|
|
'content': content,
|
|
'is_active': True,
|
|
'created_by': admin_user,
|
|
'updated_by': admin_user
|
|
}
|
|
)
|
|
print("Default help boxes created")
|
|
EOF
|
|
|
|
echo "=== Step 6: Verification ==="
|
|
echo "Verifying migration results..."
|
|
|
|
# Test database connectivity
|
|
if docker compose -f ../docker-compose.prod.yml exec web python manage.py check; then
|
|
echo "✓ Django system check passed"
|
|
else
|
|
echo "✗ Django system check failed"
|
|
fi
|
|
|
|
# Test web interface
|
|
if curl -f -s http://localhost:8000/health/ > /dev/null; then
|
|
echo "✓ Web interface is responding"
|
|
else
|
|
echo "✗ Web interface is not responding"
|
|
fi
|
|
|
|
# Count migrated objects
|
|
echo "Migration summary:"
|
|
docker compose -f ../docker-compose.prod.yml exec web python manage.py shell << 'EOF'
|
|
from django.apps import apps
|
|
for model in apps.get_models():
|
|
if hasattr(model, '_meta') and model._meta.app_label == 'stiftung':
|
|
count = model.objects.count()
|
|
print(f" {model.__name__}: {count} objects")
|
|
EOF
|
|
|
|
echo ""
|
|
echo "=== Migration Complete! ==="
|
|
echo ""
|
|
echo "Your application has been migrated from Synology to Ubuntu server."
|
|
echo ""
|
|
echo "What to test:"
|
|
echo "1. Login with your new superuser account"
|
|
echo "2. Verify all data is present and correct"
|
|
echo "3. Test HelpBox system on creation pages"
|
|
echo "4. Test PDF exports and reports"
|
|
echo "5. Verify Förderung search functionality"
|
|
echo ""
|
|
echo "Access your application at:"
|
|
echo " - Main app: http://217.154.84.225"
|
|
echo " - Admin: http://217.154.84.225/admin/"
|
|
echo " - HelpBox Admin: http://217.154.84.225/help-box/admin/"
|
|
echo ""
|
|
echo "If everything works correctly, you can:"
|
|
echo "1. Update your DNS to point to the new server"
|
|
echo "2. Set up SSL certificates"
|
|
echo "3. Decommission the old Synology deployment"
|
|
|
|
cd ..
|
|
echo "Migration data is preserved in: /opt/stiftung/migration-data/"
|