diff --git a/RESTORE.md b/RESTORE.md new file mode 100644 index 0000000..993c1f2 --- /dev/null +++ b/RESTORE.md @@ -0,0 +1,338 @@ +# Restoration Guide + +This guide walks you through restoring your Docker infrastructure from a backup. + +## Prerequisites + +- Fresh system with Docker and Docker Compose installed +- Backup archive (`docker-backup-YYYYMMDD_HHMMSS.tar.gz`) +- Access to NAS storage (if applicable) +- Root or sudo access + +## Step 1: Extract Backup + +```bash +# Navigate to your backup location +cd /path/to/backups + +# Extract the backup archive +tar xzf docker-backup-YYYYMMDD_HHMMSS.tar.gz + +# Navigate into the extracted backup +cd YYYYMMDD_HHMMSS +``` + +## Step 2: Restore Directory Structure + +```bash +# Copy the directory structure script +cp directory_structure.sh /opt/docker-compose/ +cd /opt/docker-compose/ + +# Make it executable and run +chmod +x directory_structure.sh +./directory_structure.sh +``` + +## Step 3: Restore Docker Compose Configuration + +```bash +# Copy main configuration files +cp /path/to/backup/docker-compose.yaml . +cp /path/to/backup/.env . +cp /path/to/backup/.gitignore . +cp /path/to/backup/README.md . + +# IMPORTANT: Edit .env file with new system-specific values +nano .env + +# Verify the configuration +docker compose config +``` + +## Step 4: Restore Service Configurations + +```bash +# Copy service configurations back to /docker +rsync -av /path/to/backup/docker/ /docker/ + +# Set correct permissions +PUID=$(id -u) +PGID=$(id -g) +sudo chown -R $PUID:$PGID /docker +``` + +## Step 5: Restore Docker Volumes + +For each volume backup in `/path/to/backup/volumes/`: + +```bash +# Create the volume if it doesn't exist +docker volume create VOLUME_NAME + +# Restore the volume data +docker run --rm \ + -v VOLUME_NAME:/volume \ + -v /path/to/backup/volumes:/backup \ + alpine \ + tar xzf /backup/VOLUME_NAME.tar.gz -C /volume +``` + +Example for specific volumes: + +```bash +# Restore Portainer data +docker volume create portainer_data +docker run --rm \ + -v portainer_data:/volume \ + -v /path/to/backup/volumes:/backup \ + alpine \ + tar xzf /backup/portainer_data.tar.gz -C /volume + +# Restore Open WebUI data +docker volume create open-webui +docker run --rm \ + -v open-webui:/volume \ + -v /path/to/backup/volumes:/backup \ + alpine \ + tar xzf /backup/open-webui.tar.gz -C /volume + +# Repeat for other volumes... +``` + +## Step 6: Start Database Services First + +```bash +# Start only database services +docker compose up -d paperless-db immich-postgres litellm-postgres wygiwyh-db gitea-db speedtest-db npm-db + +# Wait for databases to be healthy +docker compose ps + +# Check logs for any errors +docker compose logs -f paperless-db +# Press Ctrl+C to exit logs +``` + +## Step 7: Restore Database Dumps + +### Paperless MariaDB +```bash +# Copy SQL file into container +docker cp /path/to/backup/database-dumps/paperless.sql paperless-db:/tmp/ + +# Import the database +docker exec -i paperless-db mysql -u root -p"${PAPERLESS_DB_ROOT_PASSWORD}" paperless < /path/to/backup/database-dumps/paperless.sql + +# Or import directly +docker exec -i paperless-db mysql -u root -p"${PAPERLESS_DB_ROOT_PASSWORD}" paperless < /path/to/backup/database-dumps/paperless.sql +``` + +### Immich PostgreSQL +```bash +docker exec -i immich_postgres psql -U postgres immich < /path/to/backup/database-dumps/immich.sql +``` + +### LiteLLM PostgreSQL +```bash +docker exec -i litellm-postgres psql -U litellm litellm_db < /path/to/backup/database-dumps/litellm.sql +``` + +### WYGIWYH PostgreSQL +```bash +docker exec -i WYGIWYH-db psql -U ${WYGIWYH_DB_USER} ${WYGIWYH_DB_DATABASE} < /path/to/backup/database-dumps/wygiwyh.sql +``` + +### Gitea MySQL +```bash +docker exec -i gitea-db mysql -u root -pgitea gitea < /path/to/backup/database-dumps/gitea.sql +``` + +### Speedtest Tracker MariaDB +```bash +docker exec -i speedtest-db mysql -u root -p"${SPEEDTEST_DB_PASSWORD}" speedtest < /path/to/backup/database-dumps/speedtest.sql +``` + +## Step 8: Mount NAS Storage (if applicable) + +```bash +# Create mount point +sudo mkdir -p /mnt/Nas-Storage + +# Add to /etc/fstab for permanent mounting +# Example for NFS: +# nas-server:/volume1/data /mnt/Nas-Storage nfs defaults 0 0 + +# Example for CIFS/SMB: +# //nas-server/data /mnt/Nas-Storage cifs credentials=/root/.smbcredentials,uid=1000,gid=1000 0 0 + +# Mount immediately +sudo mount -a + +# Verify mount +df -h /mnt/Nas-Storage +``` + +## Step 9: Start All Services + +```bash +# Start all services +docker compose up -d + +# Watch the startup process +docker compose logs -f + +# Check service health +docker compose ps +``` + +## Step 10: Verify Services + +Go through each service and verify it's working correctly: + +### Check Web Interfaces +- Homepage: http://your-server:7575 +- Portainer: https://your-server:9443 +- Jellyfin: http://your-server:8096 +- Paperless: http://your-server:8100 +- Immich: http://your-server:2283 + +### Verify Databases +```bash +# Paperless +docker exec paperless-db mysql -u root -p"${PAPERLESS_DB_ROOT_PASSWORD}" -e "SELECT COUNT(*) FROM paperless.documents_document;" + +# Immich +docker exec immich_postgres psql -U postgres -d immich -c "SELECT COUNT(*) FROM assets;" +``` + +### Check Logs for Errors +```bash +# View logs for specific service +docker compose logs SERVICE_NAME + +# Follow logs in real-time +docker compose logs -f SERVICE_NAME +``` + +## Step 11: Configure Reverse Proxy (NPM) + +1. Access Nginx Proxy Manager at http://your-server:81 +2. Default credentials (if fresh install): + - Email: admin@example.com + - Password: changeme +3. Recreate proxy hosts for each service +4. Restore SSL certificates (if backed up in /npm/letsencrypt) + +## Troubleshooting + +### Service Won't Start +```bash +# Check logs +docker compose logs SERVICE_NAME + +# Restart specific service +docker compose restart SERVICE_NAME + +# Check disk space +df -h + +# Check permissions +ls -la /docker/SERVICE_NAME/ +``` + +### Database Connection Errors +```bash +# Verify database is running +docker compose ps | grep db + +# Test database connection +docker exec SERVICE_NAME nc -zv DATABASE_HOST 3306 + +# Check database logs +docker compose logs DATABASE_SERVICE +``` + +### Permission Errors +```bash +# Fix ownership of Docker configs +sudo chown -R $PUID:$PGID /docker + +# Fix NAS permissions +sudo chown -R $PUID:$PGID /mnt/Nas-Storage/data +``` + +### Missing Environment Variables +```bash +# Verify .env file is loaded +docker compose config | grep VARIABLE_NAME + +# Check for typos in .env +cat .env | grep VARIABLE_NAME +``` + +### Volume Restore Failed +```bash +# Remove corrupted volume +docker volume rm VOLUME_NAME + +# Recreate and try again +docker volume create VOLUME_NAME +# ... restore command ... +``` + +## Post-Restoration Checklist + +- [ ] All services are running (`docker compose ps`) +- [ ] Web interfaces are accessible +- [ ] Databases contain expected data +- [ ] Media files are accessible +- [ ] Reverse proxy/SSL certificates work +- [ ] User accounts can login +- [ ] API keys/tokens are functional +- [ ] Scheduled tasks are running (Watchtower, etc.) +- [ ] Backups are configured + +## Partial Restoration + +If you only need to restore specific services: + +```bash +# Restore only configuration +cp -r /path/to/backup/docker/SERVICE_NAME /docker/ + +# Start only specific services +docker compose up -d SERVICE_NAME + +# Restore only specific database +docker exec -i DB_CONTAINER mysql/psql ... < backup.sql +``` + +## Notes + +- Always test restoration process on a non-production system first +- Keep multiple backup copies in different locations +- Document any custom configurations or modifications +- Update README.md if infrastructure changes +- Verify backup integrity regularly + +## Emergency Recovery + +If full restoration fails: + +1. Start with minimal services (databases only) +2. Verify database connectivity +3. Add services one at a time +4. Check logs after each addition +5. Document which services fail and why + +## Getting Help + +- Check service-specific documentation +- Review Docker logs: `docker compose logs -f` +- Verify network connectivity: `docker compose exec SERVICE ping OTHER_SERVICE` +- Check resource usage: `docker stats` + +--- + +**Last Updated**: December 2025