Migration from Upstream

Bazarr+ is a drop-in replacement for upstream Bazarr. It uses a compatible database with additional columns added on first run, the same config files, and the same volume paths. Switching takes about five minutes.

Back up your config

Before making any changes, copy your entire config directory. This is the directory you mounted as /config in your existing Bazarr container.

Shell
cp -r ./config ./config-backup-$(date +%Y%m%d)

This gives you a timestamped backup you can restore from if anything goes wrong. The config directory contains your SQLite database (db/bazarr.db), settings, logs, and cached data.

Do not skip this step. While the migration is straightforward and non-destructive, having a backup means you can always go back.

Container swap process

The actual swap is just changing the Docker image name in your compose file.

  1. Stop the current container.
    Shell
    docker compose down
  2. Update the image in your docker-compose.yml. Change the image line from the upstream image to the Bazarr+ image:
    Before → After
    # Before (upstream)
    image: lscr.io/linuxserver/bazarr:latest
    # or
    image: ghcr.io/morpheus65535/bazarr:latest
    
    # After (Bazarr+)
    image: ghcr.io/lavx/bazarr:latest
  3. Add the companion services. Add the OpenSubtitles scraper, FlareSolverr, and AI translator to your compose file. Set the scraper URL on the bazarr service:
    docker-compose.yml additions
    # Add to bazarr service environment:
        environment:
          - OPENSUBTITLES_SCRAPER_URL=http://opensubtitles-scraper:8000
    
    # Add these services:
      opensubtitles-scraper:
        image: ghcr.io/lavx/opensubtitles-scraper:latest
        container_name: opensubtitles-scraper
        restart: unless-stopped
        depends_on:
          flaresolverr:
            condition: service_healthy
        ports:
          - 8000:8000
        environment:
          - FLARESOLVERR_URL=http://flaresolverr:8191/v1
        healthcheck:
          test: ["CMD", "curl", "-sf", "http://localhost:8000/health"]
          interval: 30s
          timeout: 10s
          retries: 3
          start_period: 10s
    
      flaresolverr:
        image: ghcr.io/flaresolverr/flaresolverr:latest
        container_name: flaresolverr
        restart: unless-stopped
        environment:
          - LOG_LEVEL=info
        healthcheck:
          test: ["CMD", "curl", "-sf", "http://localhost:8191/health"]
          interval: 30s
          timeout: 10s
          retries: 3
          start_period: 60s
    
      # AI translation via OpenRouter (free tiers available)
      # Configure the API key in Settings > AI Translator
      ai-subtitle-translator:
        image: ghcr.io/lavx/ai-subtitle-translator:latest
        container_name: ai-subtitle-translator
        restart: unless-stopped
        ports:
          - 8765:8765
        healthcheck:
          test: ["CMD", "curl", "-sf", "http://localhost:8765/health"]
          interval: 30s
          timeout: 10s
          retries: 3
          start_period: 10s
  4. Start the new stack.
    Shell
    docker compose up -d

That is it. Open Bazarr+ in your browser and everything should be where you left it.

What changes

After the swap, you get all the Bazarr+ additions on top of your existing setup:

  • Provider priority. A toggle in Settings > Subtitle Sources enables priority-ordered querying with early stop.
  • Bulk operations. Series and Movies pages gain checkboxes and a batch action toolbar.
  • Subtitle editor. A new "Edit" button appears next to each downloaded subtitle.
  • AI translation. Translate subtitles into any language via OpenRouter models. Configure in Settings > AI Translator.
  • Telemetry removed. All Google Analytics tracking code is gone. No data leaves your server.
  • UI improvements. Navigation changes, keyboard shortcuts, and various polish throughout.

What stays the same

  • Database. Your SQLite database is used as-is. Bazarr+ adds a few columns via Alembic migrations on first run (e.g. score_out_of, tvdbId), but these do not break backwards compatibility.
  • Settings. All your provider accounts, language profiles, Sonarr/Radarr connections, and notification settings carry over.
  • History. Your entire download and upgrade history remains intact.
  • Subtitles. All previously downloaded subtitle files stay on disk, untouched.
  • Scheduled tasks. Your scan intervals and other scheduled tasks continue as configured.

Password upgrade notice

Upstream Bazarr stores passwords using MD5, which is insecure. On first login after the migration, Bazarr+ will transparently upgrade your password hash to PBKDF2 with 600,000 iterations. This happens automatically when you enter your existing password. No action needed on your part.

Note: If you later revert to upstream Bazarr, you will need to reset your password because upstream cannot read the PBKDF2 hash. See the section below for details.

Reverting if needed

If you want to switch back to upstream Bazarr for any reason:

  1. Stop Bazarr+. Run docker compose down.
  2. Restore your backup. Replace the current config directory with your backup: rm -rf ./config && cp -r ./config-backup-* ./config
  3. Change the image back to the upstream image in your compose file.
  4. Start it. Run docker compose up -d.

If you did not keep a backup and want to revert, there are a few things to be aware of. The password hash in config/config.yaml under auth.password will be in PBKDF2 format, which upstream cannot read. Clear the password field to reset it. Additionally, the series_scores and movie_scores config sections are deleted by Bazarr+, gemini_key is migrated to a gemini_keys list, and the analytics section is removed.

Next steps