Clean up docker-compose configuration
- Archive deploy-production directory as deploy-production-archived (legacy) - Add DOCKER_COMPOSE_README.md for documentation - Main configuration now uses compose.yml with working Paperless integration - Paperless API URL configured as https://vhtv-stiftung.de/paperless
This commit is contained in:
234
deploy-production-archived/migrate-data.sh
Normal file
234
deploy-production-archived/migrate-data.sh
Normal file
@@ -0,0 +1,234 @@
|
||||
#!/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/"
|
||||
Reference in New Issue
Block a user