University of Michigan Library containerization of DSpace
A source image is created by pulling source code from the library's forks of DSpace: https://github.com/mlibrary/dspace-angular and https://github.com/mlibrary/DSpace. The source image is then used to create the frontend, backend, and solr images. These images, along with a database image, are then configured and deployed to create an instance of the DSpace application.
Essentially there are two, for lack of a better word, contexts: local and remote. Local will be used to refer to your local development environment, or more specifically, Docker Desktop. Remote will be used to refer a Kubernetes cluster. The primary differences between these two contexts being how images are built, where they are stored, and how they are deployed. Local images are built via the docker compose build command, stored locally in Docker Desktop, and deployed via docker compose up -d command. Remote images are built via GitHub Actions, stored remotely in GitHub Packages, and deployed to Kubernetes (OpenShift) typically using kubectl (oc) to apply the appropriate deployment yaml files.
It is recommend that you first get an instance of DSpace running locally via docker compose prior to attempting to get an instance of DSpace running remotely in Kubernetes.
- (Optional) Copy
.env.exampleto.envand adjust build arguments as needed. - Build the shared source image (required once, and whenever the source branch changes):
docker build -t dspace-containerization-source .The
frontend,backend, andsolrimages depend on this image at build time. Usemake build(see Makefile) to build source + all compose services in one step. - Build the compose service images:
docker compose build
- Start the core services:
docker compose up -d
dbandsolrinclude healthchecks;backendwill not start until both are healthy.
The apache and express services are not started by default. To include them:
docker compose --profile optional up -dOr start a single optional service:
docker compose --profile optional up -d apache
docker compose --profile optional up -d express| URL | Container | Comments |
|---|---|---|
| http://localhost:4000/ | frontend | Angular GUI (SSR app shell; Angular router handles /home etc. client-side) |
| jdbc:postgresql://localhost:5432/dspace | db | PostgreSQL (user: dspace, password: dspace) |
| http://localhost:8080/server | backend | Server API |
| http://localhost:8983/solr | solr | Solr GUI |
| http://localhost:8888/ | apache | Apache Web Server – optional (CGI stats scripts) |
| http://localhost:3000/metrics | express | Prometheus metrics endpoint – optional |
Build arguments are read from .env (copy from .env.example):
GITHUB_BRANCH=umich
DSPACE_VERSION=7.6
JDK_VERSION=17
GITHUB_BRANCH— branch in the mlibrary forks used to build the source image.DSPACE_VERSION— version suffix for DSpace Docker Hub images (e.g.7.6→ image tagdspace-7.6). Use7.6here; the current upstream DSpace patch release targeted by this configuration is 7.6.6 (Dec 2025).JDK_VERSION— Java version for the backend Tomcat image (17recommended;11also supported). The build useseclipse-temurinimages — the official successor to the deprecatedopenjdkDocker Hub images.
docker-compose.yml passes DSPACE_VERSION and JDK_VERSION automatically to the relevant service builds via build.args.
- Debugging ports (e.g., 8009, 9876) are not exposed by default. Add them to
docker-compose.ymlif needed. - The
backendservice usesdepends_onwithcondition: service_healthyfordbandsolr, ensuring correct startup ordering without manual delays. - Use
maketargets (see Makefile) for common workflows:make build,make up,make down,make clean.
A shell-based smoke test suite lives in tests/. It requires only bash and curl.
bash tests/smoke.shmake testThis is equivalent to:
make up # docker compose up -d
bash tests/wait-for-stack.sh # poll until backend/solr/frontend are ready
bash tests/smoke.sh # run all assertions| Layer | Endpoint | Assertion |
|---|---|---|
| Backend REST API | GET /server/api |
HTTP 200, HAL _links present |
| Backend REST API | GET /server/api/core/communities |
HTTP 200 |
| Backend REST API | GET /server/api/core/collections |
HTTP 200 |
| Backend REST API | GET /server/api/authn/status |
HTTP 200, "authenticated":false |
| Backend REST API | GET /server/api/info/status |
HTTP 200, dspaceVersion field present |
| Backend Actuator | GET /server/actuator/health |
"status":"UP" |
| Solr | GET /solr/admin/info/system |
HTTP 200, version info present |
| Solr | GET /solr/admin/cores |
All four DSpace cores present (authority, oai, search, statistics) |
| Solr | GET /solr/search/admin/ping |
HTTP 200 |
| Frontend | GET / |
HTTP 200, ds-root element present (DSpace Angular root), no error boundary |
The workflow .github/workflows/integration-test.yml runs the full suite automatically on pushes that affect dockerfiles or test files, and can also be triggered manually with custom dspace_version/jdk_version inputs.