This guide walks through the complete process of migrating Audiobookshelf v2.28.0 from one Ubuntu server to another while changing the media path structure, preserving all your listening history, user progress, and metadata.
The Challenge
In our case, we needed to migrate from:
- Old path:
/media/oldserver/storage/Media/Books/
- New path:
/mnt/newserver/Media/Books/
The Audiobookshelf backup contains SQLite database files with hardcoded paths. Simply restoring the backup results in a library that shows all your books and progress, but can’t access the actual media files.
Prerequisites
- Source server with working Audiobookshelf installation
- Destination server with fresh Audiobookshelf installation
- Administrative access to both servers
- Basic familiarity with command line and SQLite
Step 1: Create and Transfer the Backup
On your source server, create a backup through the web interface:
- Go to Settings → Backups
- Click Create Backup
- Download the generated
.audiobookshelf
file
Transfer your media files to the new server and note the new path structure.
Step 2: Fresh Installation and Initial Restore
On your destination server:
- Install Audiobookshelf normally
- Restore the backup through the web interface
- At this point, your library will appear but media files won’t be accessible
Step 3: Database Path Migration
This is where the magic happens. We need to update the hardcoded paths in the SQLite database.
Stop the Service
systemctl stop audiobookshelf.service
Navigate to the Database
cd /usr/share/audiobookshelf/config
Backup the Database
cp absdatabase.sqlite absdatabase.sqlite.backup
Update the Paths
Execute these SQL commands to replace old paths with new ones:
-- Update library folder paths (most critical)
UPDATE libraryFolders
SET path = REPLACE(path, '/media/oldserver/storage/', '/mnt/newserver/')
WHERE path LIKE '%/media/oldserver/storage/%';
-- Update library item paths
UPDATE libraryItems
SET path = REPLACE(path, '/media/oldserver/storage/', '/mnt/newserver/')
WHERE path LIKE '%/media/oldserver/storage/%';
-- Update book cover paths
UPDATE books
SET coverPath = REPLACE(coverPath, '/media/oldserver/storage/', '/mnt/newserver/')
WHERE coverPath LIKE '%/media/oldserver/storage/%';
-- Update JSON fields containing file paths
UPDATE libraryItems
SET libraryFiles = REPLACE(libraryFiles, '/media/oldserver/storage/', '/mnt/newserver/')
WHERE libraryFiles LIKE '%/media/oldserver/storage/%';
UPDATE books
SET audioFiles = REPLACE(audioFiles, '/media/oldserver/storage/', '/mnt/newserver/')
WHERE audioFiles LIKE '%/media/oldserver/storage/%';
UPDATE books
SET ebookFile = REPLACE(ebookFile, '/media/oldserver/storage/', '/mnt/newserver/')
WHERE ebookFile LIKE '%/media/oldserver/storage/%';
Verify the Changes
-- Check library folders
SELECT path FROM libraryFolders;
-- Check a few library items
SELECT path FROM libraryItems LIMIT 5;
-- Check cover paths
SELECT coverPath FROM books WHERE coverPath IS NOT NULL LIMIT 5;
-- Exit SQLite
.quit
Step 4: Fix File Permissions
This step is crucial and often overlooked. Your media files might be owned by a different user than the Audiobookshelf service.
Check Service User
ps aux | grep audiobookshelf
Set Correct Permissions
If your media files are owned by user mediauser
and Audiobookshelf runs as user audiobookshelf
, add the service user to the media group and set permissions:
usermod -a -G mediauser audiobookshelf
chmod -R g+r "/mnt/newserver/Media/Books/"
find "/mnt/newserver/Media/Books/" -type d -exec chmod g+x {} \;
Step 5: Start Service and Refresh
Start Audiobookshelf
systemctl start audiobookshelf.service
Clear Cache and Rescan
- Stop the service:
systemctl stop audiobookshelf.service
- Clear cache:
rm -rf /usr/share/audiobookshelf/metadata/cache/*
- Start service:
systemctl start audiobookshelf.service
- In the web interface: Settings → Libraries → Force Re-Scan
Common Issues and Solutions
Database Schema Corruption
Symptom: Error: malformed database schema
when running .tables
Solution: Use recovery mode when opening the database:
sqlite3 -cmd ".recover" absdatabase.sqlite
Permission Denied Errors
Symptom: Service fails to start with EACCES: permission denied
Solution: Ensure the service user has access to all necessary directories:
chown -R audiobookshelf:audiobookshelf /usr/share/audiobookshelf/config/
chown -R audiobookshelf:audiobookshelf /usr/share/audiobookshelf/metadata/
Alternative Approaches
If you don’t care about preserving user listening history, progress, or metadata, you can simply restore the backup, update the library path in the settings, and rescan.
⚠️ Not Recommended
This approach will likely create duplicate entries and will completely lose the connection between existing user progress and the media files. Only consider this if you’re willing to start fresh with all user data.
Conclusion
While Audiobookshelf doesn’t have built-in path remapping during restore, direct database editing provides a reliable way to migrate between servers with different path structures. The key is being methodical about updating all path references and ensuring proper file permissions.
Troubleshooting Checklist
- ☐ Database backup created
- ☐ All path
UPDATE
queries executed successfully - ☐ File permissions configured correctly
- ☐ Service starts without errors
- ☐ Library rescan completed
- ☐ Covers loading properly
- ☐ Listening progress preserved
- ☐ Browser cache cleared
Remember: when in doubt, force a library rescan. It solves more problems than you’d expect!