How to Migrate DSpace 8.x to DSpace 10.x on Ubuntu (Step-by-Step Guide)
DSpace 8.x → 10.x Migration Guide
Fresh Installation + Data Migration
This guide follows a migration approach: install DSpace 10.x fresh and move the existing DSpace 8.x database, assetstore, configuration, and required supporting data. It is not an in-place upgrade.
Environment reference (fill in / confirm before running on a new box):
| Component | Reference |
|---|---|
| Old server | DSpace 8.x, hostname dspace-8x |
| New install | fresh DSpace 10.x at /dspace |
| Solr | /opt/solr (Solr home: /opt/solr/server/solr) |
| Target DB | dspace10 (Postgres 16, role dspace) |
| 8.x backup location | /home/dspace/Downloads/Dspace_8.X_BKP/Dspace_8X._BKP_July_2026/ |
This is the migration approach (fresh 10.x install + move data over), not an in-place upgrade — recommended since you're skipping a major version (9.x) and already had 10.x installed fresh.
1. Backup the 8.x source (if not already done)
# DB dump
pg_dump -U [dspace8-db-user] -f dspace8_backup.sql [dspace8-db-name]
# Assetstore, config, solr
tar czf assetstore_backup.tar.gz -C [dspace8]/assetstore .
tar czf dspace8_config.tar.gz -C [dspace8]/config .
tar czf solr_backup.tar.gz -C [dspace8]/solr .
2. Create the target database
sudo -u postgres createuser --username=postgres --no-superuser --pwprompt dspace # skip if exists
sudo -u postgres createdb --username=postgres --owner=dspace --encoding=UTF8 --locale=en_US.UTF-8 dspace10
3. Grant schema permissions (required on Postgres 15+)
sudo -u postgres psql -d dspace10
GRANT ALL PRIVILEGES ON DATABASE dspace10 TO dspace;
GRANT ALL ON SCHEMA public TO dspace;
ALTER SCHEMA public OWNER TO dspace;
\q
sudo -u postgres psql -d dspace10 -c "CREATE EXTENSION IF NOT EXISTS pgcrypto;"
4. Restore the DB dump
psql -U dspace -h 127.0.0.1 -d dspace10 -f /path/to/dspace8_backup.sql
Verify:
psql -U dspace -h 127.0.0.1 -d dspace10 -c "\dt" | head -20
psql -U dspace -h 127.0.0.1 -d dspace10 -c "SELECT count(*) FROM item;"
psql -U dspace -h 127.0.0.1 -d dspace10 -c "SELECT count(*) FROM eperson;"
5. Point local.cfg at the restored DB
nano /dspace/config/local.cfg
db.url = jdbc:postgresql://127.0.0.1:5432/dspace10
db.username = dspace
db.password = [password]
db.dialect = org.dspace.util.DSpacePostgreSQLDialect
6. Migrate the schema
/dspace/bin/dspace database info # check pending/ignored migrations first
/dspace/bin/dspace database migrate ignored
/dspace/bin/dspace database info # confirm all Success, no Pending/Ignored
migrate ignored is required specifically when coming from 8.x — it also picks up any legacy migrations flagged "Ignored" from your DB's older history. "Out of Order" status on old entries after this is expected/harmless.
7. Restore the assetstore
Check source vs zip for freshness first, then:
rsync -av [8x-backup]/dspace/assetstore/ /dspace/assetstore/
chown -R tomcat:tomcat /dspace/assetstore # match your actual service user
chmod -R 750 /dspace/assetstore
Verify:
du -sh /dspace/assetstore
find /dspace/assetstore -type f | wc -l
psql -U dspace -h 127.0.0.1 -d dspace10 -c "SELECT count(*) FROM bitstream WHERE deleted=false;"
grep -r "assetstore" /dspace/config/local.cfg /dspace/config/spring/api/bitstore.xml 2>/dev/null
8. Solr — do NOT copy old core folders into configsets/
/dspace/solr/* contains full core directories (with core.properties + data/), not bare configsets. Never copy them directly into /opt/solr/server/solr/configsets/ — that creates duplicate-core-name conflicts and crashes the CoreContainer entirely (Found multiple cores with the name [x]).Your fresh 10.x install already creates correct, live cores under /opt/solr/server/solr/<corename>/ — leave those alone. Just confirm Solr starts clean:
systemctl restart solr
systemctl status solr
tail -30 /opt/solr/server/logs/solr.log
Cores are: [statistics, qaevent, authority, audit, oai, suggestion, search] — no duplicates, no CoreContainerProvider error.If you previously made this mistake, fix with:
cd /opt/solr/server/solr/configsets
rm -rf statistics qaevent authority audit oai suggestion search
systemctl restart solr
Verify:
curl http://localhost:8983/solr/search/select?q=*:*
curl http://localhost:8983/solr/statistics/select?q=*:*
data/index contents from your 8.x backup's solr/statistics (and authority) cores into the corresponding *already-created* /opt/solr/server/solr/<core>/data/ — never through configsets/.9. Reindex
/dspace/bin/dspace index-discovery -b
/dspace/bin/dspace oai import
10. DOI metadata migration (DSpace 10 changed the DOI field/format)
Check the "Standardizing the format and location of DOI metadata" section on the DSpace 10.x wiki, then run the DOI migrator script referenced there before relying on DOIs in production.
11. Metadata registries (usually auto-triggered by step 6, run manually if not)
cd /dspace/bin/
./dspace registry-loader -metadata ../config/registries/dcterms-types.xml
./dspace registry-loader -metadata ../config/registries/dublin-core-types.xml
./dspace registry-loader -metadata ../config/registries/eperson-types.xml
./dspace registry-loader -metadata ../config/registries/local-types.xml
./dspace registry-loader -metadata ../config/registries/sword-metadata.xml
./dspace registry-loader -metadata ../config/registries/workflow-types.xml
12. Config diff — don't overwrite, merge selectively
diff -rq [8x-backup]/dspace/config /dspace/config
Pull over only: your old local.cfg values (merge in, check against 10.x Release Notes "Breaking Changes" for renamed/removed keys), custom modules/*.cfg overrides, and any customized config/spring/api/bitstore.xml.
13. Frontend (Angular UI) — breaking changes inherited from 9.x AND 10.x since you're skipping 9.x
- Bootstrap 5 (introduced 9.0): migrate any custom theme CSS/SASS — see Bootstrap 5 migration guide.
- Angular control-flow syntax (required as of 10.0): convert
ngIf/ngForto@if/@forin*.component.html:
```bash
cd [dspace-angular]
npx @angular/cli generate @angular/core:control-flow --path src/themes/[your-theme]
```
- Theme config format was simplified in 10.0 — check "Upgrading from 9.x to 10.x" on the User Interface Customization wiki page before editing
theme.config.ts.
Build:
cd [dspace-angular]
npm run clean
npm install
npm run build:prod
14. Cron / scheduled tasks
Confirm subscription-send is in crontab (replaces old sub-daily, required since 7.5).
15. Restart everything and verify
# Backend (PM2/runnable JAR)
pm2 stop dspace-ui.json
pm2 start dspace-ui.json
# or Tomcat
$CATALINA_HOME/bin/shutdown.sh && $CATALINA_HOME/bin/startup.sh
Then check:
tail -100 /dspace/log/dspace.log.$(date +%Y-%m-%d)
Hit the REST API (/server/api) and the UI, confirm items/search/browse are populated, and spot-check a few records against the old 8.x site.
Known gotchas hit during this migration (for next time)
- Postgres peer auth — connecting as
root/wrong OS user via local socket fails even with-U dspace; use-h 127.0.0.1to force password auth, orsudo -u dspace psql. - Public schema ownership — Postgres 15+ no longer grants
CREATEonpublicto all roles by default; mustALTER SCHEMA public OWNER TO dspaceexplicitly. - Solr configsets vs cores —
/dspace/solr/*are full cores, not configsets. Copying them intoconfigsets/causes duplicate-core-name crashes on Solr startup.
Comments
Post a Comment