The DSpace User Interface built on Angular, written in TypeScript and using Angular Universal.
This is a fork of https://github.com/DSpace/dspace-angular modified to function as a frontend for clarin-dspace. Please refer to Installation Wiki or the clarin-dspace v7 wiki
NOTE: this is the appended setup guide for CLARIN-DK's DSpace repository.
- The new main repo of the CLARIN DSpace is now the frontend repo (
dspace-angular), not the backend one (clarin-dspace). - The branch which contains our downstream changes is called
clarin-dk-v7.- Consider this the de facto master/main branch.
- It contains just enough changes to make running a CLARIN-DK DSpace Docker setup possible in our dev/prod environments.
- It needs to be regularly rebased on the stable branch of the CLARIN DSpace v7 fork (the one maintained by ufal).
- When rebasing, expect occasional merge conflicts for this README.md (as well as other files touched in the meantime).
- The previous CLARIN DSpace repo had a branch which contained downstream changes called
clarin-dk-ucph, though that was for the older v5 of DSpace.
- The
.gitignoreof this repo has.envadded to it, so we use.env.localas our primary .env file. - S3 support has been explicitly disabled in
docker/local.cfg. - The handle server has been configured in
docker/local.cfgwith our handle prefix:handle.additional.prefixes = 20.500.12115.
The Shibboleth SP runs on the host (/etc/shibboleth/), not inside any Docker container. Both DSpace v5 (repository.clarin.dk) and v7 (dspace.clarin.dk) share a single SP with one entity ID registered in the CLARIN federation:
entityID = https://repository.clarin.dk/shibboleth shibboleth2.xml routes the two instances via RequestMapper + ApplicationOverride:
| Host | applicationId | Default ACS index | ACS endpoint |
|---|---|---|---|
repository.clarin.dk | default | 1 | https://repository.clarin.dk/Shibboleth.sso/SAML2/POST |
dspace.clarin.dk | dspace7 | 5 | https://dspace.clarin.dk/Shibboleth.sso/SAML2/POST |
Both sets of ACS endpoints are declared in the metadata template (repository.clarin.dk.template.metadata.xml) and in the federation metadata at https://infra.clarin.eu/aai/prod_md_about_spf_sps.xml.
Do not change the entity ID without coordinating with the CLARIN federation — it must match what is registered there. If login fails with "Issuer is not among trusted", the problem is likely on the IdP side; verify against the federation metadata before touching the SP config.
Config changes take effect on sudo systemctl restart shibd — no Docker rebuild needed.
The v5 to v7 migration uses code from a separate repo. High-level process:
- Clone migration tool and install dependencies
- Start fresh v7 DSpace instance
- Load v5 database dumps into Postgres container
- Transfer v5 assetstore files (required for complete migration)
- Configure migration tool (
project_settings.py) - Run migration via REST API
Important: Migration must be performed with full assetstore access. Post-migration file addition doesn't work.
For detailed step-by-step instructions, see https://github.com/kuhumcst/dspace-v7-data
Symptoms: POST [core/communities] failed. Exception: [<Response [500]>], backend logs show "handle already in use", 0 items imported.
Cause: Migration tool uses cache in src/__temp/resume/. After docker compose down -v, cached UUIDs are stale.
Solution:
# Reset everything cd /path/to/dspace-angular docker compose --env-file .env.local -p dspace-test -f docker/docker-compose.yml -f docker/docker-compose-rest.yml down -v docker compose --env-file .env.local -p dspace-test -f docker/docker-compose.yml -f docker/docker-compose-rest.yml up -d --pull always docker logs -f dspace0 # Wait for startup # Recreate admin docker compose --env-file .env.local -p dspace-test -f docker/docker-compose.yml -f docker/docker-compose-rest.yml -f docker/cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f Test -l Admin -p password -c en -o Test # Reload v5 databases docker exec dspacedb0 createdb -U dspace -p 5430 clarin-dspace docker exec dspacedb0 createdb -U dspace -p 5430 clarin-utilities cat /path/to/clarin-dspace.sql | docker exec -i dspacedb0 psql -U dspace -p 5430 clarin-dspace cat /path/to/clarin-utilities.sql | docker exec -i dspacedb0 psql -U dspace -p 5430 clarin-utilities # Delete cache and re-run cd /path/to/dspace-migrate rm -rf src/__temp/resume/ source .venv/bin/activate cd src python repo_import.py --resume FalseVerification: Should see OK Imported [ 1] communities, OK Imported [ 2] collections in logs.
Best practice: Always clean cache (rm -rf src/__temp/resume/) and use --resume False when restarting from scratch.
# Start CLARIN-DSpace v7 locally # --env-file .env.local Use our local environment config # -p dspace-test Project name (prefixes container names) # -f docker/docker-... Compose files for frontend and backend # -d Run in background (detached) # --pull always Always fetch latest images before starting docker compose --env-file .env.local -p dspace-test -f docker/docker-compose.yml -f docker/docker-compose-rest.yml up -d --pull always # Restart (e.g. after config changes) docker compose --env-file .env.local -p dspace-test -f docker/docker-compose.yml -f docker/docker-compose-rest.yml down docker compose --env-file .env.local -p dspace-test -f docker/docker-compose.yml -f docker/docker-compose-rest.yml up -d # Full reset (wipes all data) docker compose --env-file .env.local -p dspace-test -f docker/docker-compose.yml -f docker/docker-compose-rest.yml down -v docker compose --env-file .env.local -p dspace-test -f docker/docker-compose.yml -f docker/docker-compose-rest.yml up -d --pull always # View backend logs docker logs -f dspace0 # Run DSpace CLI commands docker compose --env-file .env.local -p dspace-test -f docker/docker-compose.yml -f docker/docker-compose-rest.yml -f docker/cli.yml run --rm dspace-cli <command># Pull in new upstream changes from UFAL (to rebase on) git fetch upstreamThe production deployment (clarinrepo01fl) runs as two separate Compose projects from docker/. Both use docker/.env (auto-loaded, INSTANCE=1).
Important: Always pass
-fexplicitly. The override file references backend services, so plaindocker composewithout-fwill fail.
| Project | Services | Command prefix |
|---|---|---|
d7 (backend) | dspace, dspacedb, dspacesolr | docker compose -p d7 -f docker-compose-rest.yml -f docker-compose.override.yml |
docker (frontend) | dspace-angular | docker compose -f docker-compose.yml |
| Change | Action needed |
|---|---|
docker/local.cfg | Restart dspace only — it's a bind mount |
Source code in src/ | Frontend rebuild (~20 min) |
package.json / yarn.lock | Frontend rebuild, yarn install also re-runs (~30 min total) |
Dockerfile | Frontend rebuild, no layer cache available |
The AAI files (aai.js, aai_config.js, discojuice/discojuice.js under src/aai/) are plain JS — never compiled by Angular — and can be pushed live with docker cp, no restart needed. Anything under src/app/ or src/themes/ requires a full rebuild.
Each file exists at three paths in the container (dist/browser/, dist/server/, src/); SSR and the browser client each read a different one, so all three must be updated. discojuice.js additionally ships .gz/.br companions in dist/browser/ that nginx picks from — regenerate them after every edit. The container has no brotli CLI; use Node's built-in zlib (the node -e command below). aai.js and aai_config.js have no compressed copies.
# aai.js (repeat pattern for aai_config.js as needed) docker cp src/aai/aai.js dspace-angular1:/app/dist/browser/aai.js docker cp src/aai/aai.js dspace-angular1:/app/dist/server/aai.js docker cp src/aai/aai.js dspace-angular1:/app/src/aai/aai.js # discojuice.js + regenerate .gz/.br docker cp src/aai/discojuice/discojuice.js dspace-angular1:/app/dist/browser/discojuice.js docker cp src/aai/discojuice/discojuice.js dspace-angular1:/app/dist/server/discojuice.js docker cp src/aai/discojuice/discojuice.js dspace-angular1:/app/src/aai/discojuice/discojuice.js docker exec dspace-angular1 node -e " const fs = require('fs'), zlib = require('zlib'); const src = fs.readFileSync('/app/dist/browser/discojuice.js'); fs.writeFileSync('/app/dist/browser/discojuice.js.gz', zlib.gzipSync(src)); fs.writeFileSync('/app/dist/browser/discojuice.js.br', zlib.brotliCompressSync(src));"Ephemeral: edits vanish on container recreate/rebuild. Commit source changes to
clarin-dk-v7so the next build picks them up.
cd /opt/dspace7/frontend # 1. Rebase onto upstream (add remote first if missing) git remote add upstream https://github.com/ufal/dspace-angular.git # if needed git fetch upstream git rebase upstream/clarin-v7 # → resolve any conflicts, then: git rebase --continue # 2. Rebuild frontend cd docker docker compose -f docker-compose.yml up -d --build # 3. Restart backend (only if local.cfg changed) docker compose -p d7 -f docker-compose-rest.yml -f docker-compose.override.yml restart dspace # 4. Verify both are healthy curl -s http://127.0.0.1:8081/server/api | head -5 # backend curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:4001 # frontend → 200 # 5. Push (force required — rebase rewrites history) cd /opt/dspace7/frontend git push --force-with-lease origin clarin-dk-v7To amend a missed change into the latest commit instead of rebasing: git add <file> && git commit --amend --no-edit, rebuild/restart as needed, then push the same way.
| Stage | Time |
|---|---|
yarn install | ~10–12 min (skipped if package.json/yarn.lock unchanged) |
Angular AOT + SSR (yarn build:prod) | ~18–20 min (always runs on source changes) |
Backend (dspace) restart | ~6 min |
yarn install is cached as long as dependency manifests haven't changed — a typical rebase that only touches src/ will skip it entirely. The Angular build produces no output during AOT compilation, so a long silence after the initial module-resolution warnings is normal, not a hang.
Only needed if something is seriously wrong or the Compose config itself changed. Volumes are preserved — no data loss.
cd /opt/dspace7/frontend/docker docker compose -p d7 -f docker-compose-rest.yml -f docker-compose.override.yml down docker compose -f docker-compose.yml down docker compose -p d7 -f docker-compose-rest.yml -f docker-compose.override.yml up -d docker compose -f docker-compose.yml up -d --buildThis version of CLARIN DSpace is more resource hungry. Recommended setup:
- CPUs: 4 cores minimum, 6+ if you can spare them (the Angular build is parallelized)
- Memory: 6-8GB
- Swap: 1-2GB
NOTE: for Apple Silicon Macs, Rosetta emulation needs to be enabled as the CLARIN DSpace Docker images are built for x86. Set
DOCKER_DEFAULT_PLATFORM=linux/amd64in your.env.local.