Maloja Import Backup

This role restores Maloja music scrobbling data from backup files created by `maloja_backup`.

Ansible Bash Docker JSON Maloja NAS YAML

Maloja Import Backup Role

Overview

This role restores Maloja music scrobbling data from backup files created by maloja_backup. It automatically identifies the latest backup, copies it to Maloja’s import directory, triggers import by restarting the container, and monitors the import process through container logs. The role is designed specifically for Docker-based Maloja deployments.

Purpose

  • Disaster Recovery: Restore scrobble history after data loss
  • Migration: Transfer scrobbles to new Maloja instance
  • Data Consolidation: Import historical scrobbles into Maloja
  • Automated Process: Handles the entire import workflow automatically
  • Progress Monitoring: Tracks import status through log parsing
  • Docker Integration: Works with dockerized Maloja deployments

Requirements

  • Ansible 2.9 or higher
  • Collection: community.docker (for docker_compose_v2 module)
  • Maloja running in Docker container
  • Docker Compose V2 installed on target host
  • Backup files created by maloja_backup role
  • NAS mount point accessible
  • Variables from docker_compositor role (docker_compose_directory, docker_data_path, docker_user)

Role Variables

Required Variables

VariableRequiredSourceDescription
docker_compose_directoryYesHost varsDocker Compose project directory
docker_data_pathYesHost varsDocker data volumes directory
docker_userYesHost varsDocker volume owner user
docker_maloja_container_nameYesHost varsMaloja container name

Optional Variables

VariableDefaultDescription
maloja_import_backup_dir{{ docker_data_path }}/maloja/importMaloja import directory path
maloja_import_backup_syno_mount_point/media/nas_win_share/maloja/exportNAS mount point with backups

Variable Details

docker_maloja_container_name

The Docker container name for Maloja. Used for log monitoring and restart commands.

Example:

docker_maloja_container_name: "maloja"

maloja_import_backup_dir

The directory where Maloja watches for import files. Files placed here are automatically imported on container restart.

Example:

maloja_import_backup_dir: /home/user/docker/maloja/import

Dependencies

This role depends on variables typically defined by:

  • docker_compositor role (for Docker paths and container configuration)
  • nas_mount or nas_mount_systemd roles (for NAS mounts)

Example Playbook

Basic Usage

---
- name: Restore Maloja Scrobbles from Backup
  hosts: docker
  become: true

  roles:
    - maloja_import_backup

With Custom Import Directory

---
- name: Restore Maloja with Custom Paths
  hosts: docker
  become: true

  vars:
    maloja_import_backup_dir: /custom/path/maloja/import
    maloja_import_backup_syno_mount_point: /mnt/backup/maloja

  roles:
    - maloja_import_backup

What This Role Does

  1. Ensures import directory exists (docker_data_path/maloja/import/)
  2. Finds all backup files on NAS matching maloja_export_*.json
  3. Sorts by modification time and selects most recent
  4. Fails gracefully if no backups found
  5. Displays backup information (filename and size in MB)
  6. Copies backup to import directory with correct ownership
  7. Restarts Maloja container to trigger import process
  8. Waits 5 seconds for container to initialize
  9. Monitors logs for “Parsing” message (import started)
  10. Displays import start message
  11. Monitors logs for “Successfully imported” message (import completed)
  12. Displays import completion message
  13. Checks for skipped scrobbles and displays count
  14. Removes import file after successful import
  15. Restarts Maloja again to clean up
  16. Displays success message

Import Process

How Maloja Import Works

Maloja automatically imports files placed in the import directory on container startup:

  1. File Detection: Maloja scans import directory on startup
  2. Parsing: Reads JSON file and validates format
  3. Duplicate Detection: Skips scrobbles that already exist
  4. Import: Adds new scrobbles to database
  5. Completion: Logs success message with counts

Log Monitoring

The role monitors Docker container logs for specific messages:

Import Started:

Parsing /mljdata/import/maloja_export_20260107_143022.json...

Import Completed:

Successfully imported 1234 scrobbles

Skipped Duplicates:

Skipped 56 scrobbles (duplicates)

Retry Logic

  • Import start: 30 retries × 2 seconds = 60 seconds timeout
  • Import completion: 120 retries × 5 seconds = 600 seconds (10 minutes) timeout

These generous timeouts accommodate large import files.

Backup File Selection

The role automatically selects the most recent backup:

  • Searches for files matching pattern: maloja_export_*.json
  • Sorts by modification time (mtime)
  • Uses the newest file

Example backup files (newest first):

maloja_export_20260107_190530.json  <- This will be used
maloja_export_20260107_143022.json
maloja_export_20260106_020000.json

File Ownership

The copied backup file is owned by docker_user to ensure Maloja container can read it:

owner: "{{ docker_user }}"
group: "{{ docker_user }}"
mode: '0644'

This is critical for container access if using volume mounts.

Duplicate Handling

Maloja automatically skips duplicate scrobbles:

  • Compares by: artist, title, and timestamp
  • Logs skipped count
  • Does not create duplicates

Example output:

Successfully imported 1000 scrobbles
Skipped 50 scrobbles (duplicates)

This makes it safe to import the same backup multiple times.

Post-Import Cleanup

After successful import, the role:

  1. Deletes the import file (prevents re-import on next restart)
  2. Restarts Maloja (clean state)
  3. Waits 5 seconds for stability

This ensures Maloja doesn’t attempt to re-import on future restarts.

Import Performance

Import speed depends on:

  • Number of scrobbles in backup
  • Duplicate detection (slower with large existing database)
  • Docker I/O performance

Typical import times:

  • 1,000 scrobbles: ~5-10 seconds
  • 10,000 scrobbles: ~30-60 seconds
  • 100,000 scrobbles: ~5-10 minutes

Error Handling

No Backup Files Found

TASK [Fail if no backup found]
fatal: [docker]: FAILED! => {"msg": "No Maloja backup files found in /media/nas_win_share/maloja/export"}

Resolution: Verify NAS is mounted and backup files exist.

Import Timeout

If import doesn’t complete within 10 minutes:

  • Check Maloja container logs: docker logs maloja
  • Verify JSON file is valid
  • Check for errors in Maloja logs

Container Restart Failures

If Maloja fails to restart:

  • Verify Docker Compose file is valid
  • Check container status: docker ps -a
  • Review Docker logs: docker compose logs maloja

Security Considerations

  • File Permissions: Import file created with mode 0644 (world-readable)
  • Owner Verification: File owned by docker_user for container access
  • Temporary Storage: Import file deleted after successful import
  • Log Exposure: Container logs may contain scrobble data

Tags

This role does not define any tags. Use playbook-level tags if needed:

- hosts: docker
  roles:
    - maloja_import_backup
  tags:
    - restore
    - maloja
    - import
    - music

Notes

  • Requires Docker Compose V2 (docker compose not docker-compose)
  • Import directory must be mounted in Maloja container
  • Maloja must be configured to watch import directory
  • Container logs are parsed with grep (requires log retention)
  • Role is idempotent but import file is consumed on first run

Troubleshooting

”Parsing” message never appears

Check:

  • Maloja container is running: docker ps
  • Import directory is mounted in container: docker inspect maloja
  • File permissions allow container to read: ls -la /path/to/import/
  • Maloja logs for errors: docker logs maloja

”Successfully imported” never appears

Check:

  • JSON file format is valid: jq . < maloja_export_20260107_143022.json
  • Maloja has enough disk space
  • Database is not corrupted
  • All scrobbles might be duplicates (check skipped count)

Import file not deleted

Indicates import didn’t complete successfully. Check Maloja logs for errors.

Container fails to restart

Verify:

  • Docker Compose file: docker compose config
  • Service definition: docker compose ps
  • Docker daemon: systemctl status docker

Skipped all scrobbles

This is normal if:

  • Importing same backup multiple times
  • Scrobbles already exist in database
  • Backup is from same Maloja instance

Maloja Configuration

Ensure Maloja is configured correctly:

docker-compose.yml

services:
  maloja:
    container_name: maloja
    image: krateng/maloja
    volumes:
      - ./maloja/data:/mljdata
      - ./maloja/import:/mljdata/import  # Important!
    environment:
      - MALOJA_DATA_DIRECTORY=/mljdata

Import Directory Structure

maloja/
├── data/
│   └── scrobbles.db
└── import/
    └── (import files placed here)

Best Practices

  1. Backup before import (in case import causes issues)
  2. Test in non-production first
  3. Verify scrobble counts after import
  4. Monitor Maloja logs during import
  5. Delete old import files manually if cleanup fails
  • maloja_backup: Creates the backup files this role imports
  • docker_compositor: Defines the Docker Compose stack with Maloja

Alternative: Manual Import

If you prefer manual import:

# Copy backup to import directory
cp /media/nas_win_share/maloja/export/maloja_export_20260107_143022.json \
   /home/user/docker/maloja/import/

# Restart Maloja
docker restart maloja

# Monitor logs
docker logs -f maloja

# Clean up after import completes
rm /home/user/docker/maloja/import/maloja_export_20260107_143022.json
docker restart maloja

License

MIT

Author

Created for homelab infrastructure management.