DSpace 10.1 Docker Compose 部署指南

DSpace 10.1 Docker Compose 部署指南:基于 2026-11-01 在跑栈实录,五服务编排(REST 后端/Angular SSR 前端/Solr 七 core/PostgreSQL 15/nginx 统一入口 8139)、database migrate 与 create-administrator 初始化全流程、JVM 堆 256–512MB 治理与 jps 验证、六则排障实录,版本线交叉复核官方最新稳定版 10.1。

DSpaceDSpaceDocker ComposeDockernginxPostgreSQLSolr知识库2026/11/01

DSpace 10.1 Docker Compose 部署指南

目标:在一台 Linux 服务器上,用官方发布件(dspace/dspace、dspace/dspace-angular、dspace/dspace-solr 的 dspace-10.1 系标签)加 PostgreSQL 15 与 nginx,编排一套完整机构知识库栈,以 8139 端口为唯一对外入口。本文全部命令与回显均为 2026-11-01 部署实录;产品定位与选型对比见《DSpace 介绍与选型指南》,配置三层优先级链与关键项详解见《DSpace 配置参数详解(env/local.cfg/dspace.cfg 三层优先级链与关键项)》,REST API 逐条实测见《DSpace REST API 使用详解(HAL 超媒体认证、CRUD 与检索实测)》。

一、环境信息

项目内容
实测日期2026-11-01
编排工具Docker Compose v5.6.1(docker compose version 实测回显 "Docker Compose version v5.6.1")
主机入口http://192.168.1.200:8139 (唯一对外端口)
REST 后端docker.io/dspace/dspace:dspace-10.1(Spring Boot 可运行 JAR server-boot.jar,内部 8080;Handle 服务内部 8000)
前端docker.io/dspace/dspace-angular:dspace-10.1-dist(Angular SSR 生产构建,内部 4000,pm2-runtime 托管)
检索docker.io/dspace/dspace-solr:dspace-10.1(内部 8983)
数据库docker.io/postgres:15(内部 5432)
反向代理docker.io/nginx:1.27-alpine(宿主 8139 → 内部 80)
专用网络dspace-101-stack_dspacenet,子网 10.89.58.0/24(docker network inspect 实测)
持久卷命名卷 assetstore(资产目录)/ pgdata(数据库)/ solr_data(索引)
JDK 口径后端 JDK 21(官方构建基线,Hibernate Validator 8.0.5.Final、Spring Boot v3.5.16 实测见第六节)
示例管理员账号admin@dspace.local / q1w2e3r4(第六节 create-administrator 实录创建)

二、版本线核对:10.1 即官方最新稳定版

部署前先核对版本线,结论(取证日期 2026-11-01):

  1. GitHub Releases 实查:DSpace/DSpace 仓库 Releases 页中,标签 dspace-10.1 带官方 Latest 徽章,发布标题 "Release DSpace 10.1 (Backend / REST API Only)"(2026-09-14);同批还有维护线 9.4、8.5 更新,上一批(2026-05-28)为 10.0/9.3/8.4/7.6.7。即本例部署的 10.1 与官方最新稳定版一致。
  2. 前端版本对齐:Angular UI 在 dspace-angular 仓库独立发布,官方镜像提供与后端版本号对齐的 dspace-10.1-dist 标签(Docker Hub 实查存在),本例直接采用。
  3. 官方警告如实记录(README 原文):"THESE IMAGES ARE NOT PRODUCTION READY"——官方发布件定位开发/测试。本文是官方发布件形态的完整可复现实录;若要生产使用,至少完成:改数据库口令与管理员口令、入口层启用 HTTPS、按第九节落实持久卷备份、按本专栏配置篇收紧 authentication-password.cfg 等安全项。

💡 技术拓展:DSpace 后端与 UI 分仓分版本发布,10.1 后端标题即注明 "REST API Only";升级时两者要分别核对兼容矩阵,不能只盯后端版本号。

三、架构与组件规划

浏览器 ──▶ http://192.168.1.200:8139
                    │
            nginx(dspace-proxy,内部 :80)
            ├── /server/ ──▶ dspace:8080          (REST 后端,/server 命名空间)
            └── /         ──▶ dspace-angular:4000 (Angular SSR 前端)
                     │
   dspace ──▶ dspacedb:5432      (PostgreSQL 15,64 张表)
   dspace ──▶ dspacesolr:8983    (Solr,7 个 core)
   dspace ──▶ /dspace/assetstore (命名卷 assetstore)

要点:

  • 五个服务同处专用网络 10.89.58.0/24,只有 proxy 映射宿主端口,后端/前端/数据库/检索均不对宿主直接暴露;
  • Solr 的 7 个 core(实测目录清单):audit、authority、oai、qaevent、search、statistics、suggestion,分别承担审计、规范引用、OAI-PMH 视图、质量事件、全站检索、使用统计、外部推荐;
  • 后端经反向代理访问,需显式信任代理网段(proxies.trusted.ipranges),否则 X-Forwarded-For 不生效、统计 IP 全部记成代理地址。

四、compose 文件全文解读

以下为在跑栈的完整编排文件(docker-compose.yml,逐行照抄):

name: dspace-10.1-stack

networks:
  dspacenet:
    ipam:
      config:
        - subnet: 10.89.58.0/24

volumes:
  assetstore:
  pgdata:
  solr_data:

services:
  # DSpace PostgreSQL database
  dspacedb:
    container_name: dspace-10.1-db
    image: docker.io/postgres:15
    environment:
      PGDATA: /pgdata
      POSTGRES_DB: dspace
      POSTGRES_USER: dspace
      POSTGRES_PASSWORD: dspace
    networks:
      - dspacenet
    volumes:
      - pgdata:/pgdata
    restart: unless-stopped

  # DSpace Solr (search/statistics cores)
  dspacesolr:
    container_name: dspace-10.1-solr
    image: docker.io/dspace/dspace-solr:dspace-10.1
    environment:
      MEM: 256m
    networks:
      - dspacenet
    working_dir: /var/solr/data
    volumes:
      - solr_data:/var/solr/data
    user: root
    entrypoint:
      - /bin/bash
      - '-c'
      - |
        init-var-solr
        precreate-core authority /opt/solr/server/solr/configsets/authority
        cp -r /opt/solr/server/solr/configsets/authority/* authority
        precreate-core oai /opt/solr/server/solr/configsets/oai
        cp -r /opt/solr/server/solr/configsets/oai/* oai
        precreate-core search /opt/solr/server/solr/configsets/search
        cp -r /opt/solr/server/solr/configsets/search/* search
        precreate-core statistics /opt/solr/server/solr/configsets/statistics
        cp -r /opt/solr/server/solr/configsets/statistics/* statistics
        precreate-core qaevent /opt/solr/server/solr/configsets/qaevent
        cp -r /opt/solr/server/solr/configsets/qaevent/* qaevent
        precreate-core suggestion /opt/solr/server/solr/configsets/suggestion
        cp -r /opt/solr/server/solr/configsets/suggestion/* suggestion
        precreate-core audit /opt/solr/server/solr/configsets/audit
        cp -r /opt/solr/server/solr/configsets/audit/* audit
        chown -R solr:solr /var/solr
        runuser -u solr -- solr-foreground
    restart: unless-stopped

  # DSpace REST backend (Spring Boot runnable jar)
  dspace:
    container_name: dspace-10.1-backend
    image: docker.io/dspace/dspace:dspace-10.1
    environment:
      dspace__P__dir: /dspace
      dspace__P__server__P__url: http://192.168.1.200:8139/server
      dspace__P__ui__P__url: http://192.168.1.200:8139
      dspace__P__server__P__ssr__P__url: http://dspace-10.1-backend:8080/server
      db__P__url: jdbc:postgresql://dspace-10.1-db:5432/dspace
      solr__P__server: http://dspace-10.1-solr:8983/solr
      proxies__P__trusted__P__ipranges: 10.89.58
      LOGGING_CONFIG: /dspace/config/log4j2-container.xml
      JAVA_TOOL_OPTIONS: -Xms256m -Xmx512m
    networks:
      - dspacenet
    volumes:
      - assetstore:/dspace/assetstore
    depends_on:
      - dspacedb
      - dspacesolr
    entrypoint:
      - /bin/bash
      - '-c'
      - |
        while (!</dev/tcp/dspace-10.1-db/5432) > /dev/null 2>&1; do sleep 1; done;
        /dspace/bin/dspace database migrate
        java -jar /dspace/webapps/server-boot.jar
    restart: unless-stopped

  # DSpace Angular UI (production dist image)
  dspace-angular:
    container_name: dspace-10.1-ui
    image: docker.io/dspace/dspace-angular:dspace-10.1-dist
    environment:
      DSPACE_UI_SSL: "false"
      DSPACE_UI_HOST: dspace-10.1-ui
      DSPACE_UI_PORT: "4000"
      DSPACE_UI_NAMESPACE: /
      DSPACE_UI_BASEURL: http://192.168.1.200:8139
      DSPACE_REST_SSL: "false"
      DSPACE_REST_HOST: 192.168.1.200
      DSPACE_REST_PORT: "8139"
      DSPACE_REST_NAMESPACE: /server
      DSPACE_REST_SSRBASEURL: http://dspace-10.1-backend:8080/server
      NODE_OPTIONS: --max-old-space-size=512
    networks:
      - dspacenet
    depends_on:
      - dspace
    restart: unless-stopped

  # Single public entry point: reverse proxy exposing UI (/) and REST (/server) on host port 8139
  dspace-proxy:
    container_name: dspace-10.1-proxy
    image: docker.io/nginx:1.27-alpine
    networks:
      - dspacenet
    ports:
      - "8139:80"
    volumes:
      - ./nginx/dspace.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - dspace-angular
    restart: unless-stopped

逐段解读:

  1. 网络:ipam 固定子网 10.89.58.0/24。多组件同机共存时给每套栈固定网段,避免 DHCP 漂移与互踩(本例占用 58 号网槽)。
  2. dspacedb:库/用户/口令三元组 dspace/dspace/dspace(演示口令,生产必改);PGDATA=/pgdata 配合命名卷,数据与安装态分离。
  3. dspacesolr:官方 dspace-solr 镜像不会自动建 core,因此 entrypoint 整段重写:init-var-solr 初始化数据目录后,用 precreate-core 逐个预建 7 个 core 并把对应 configset 拷入,最后降权到 solr 用户前台运行。MEM: 256m 控制 Solr 堆。这一段是 DSpace 检索栈编排区别于通用 Solr 编排的核心特征,漏任何一个 core,后端对应功能(检索/统计/OAI/审计等)启动即报错。
  4. dspace(后端):
    • dspace__P__xxx 形式的变量名是 DSpace 环境变量注入约定:__P__ 翻译为点号、__D__ 翻译为短横线,即 db__P__url 就是配置项 db.url(详见配置篇);
    • entrypoint 三步:先以 /dev/tcp 探测数据库端口就绪,再执行 dspace database migrate 建库/迁移,最后 java -jar server-boot.jar 起 REST 服务——数据库迁移自动内嵌在启动序列里,升级换标签后重启即完成迁移;
    • LOGGING_CONFIG 指向 log4j2-container.xml(控制台日志形态);JAVA_TOOL_OPTIONS 为堆治理入口(见第七节)。
  5. dspace-angular(前端):DSPACE_UI_*/DSPACE_REST_* 两组变量描述"浏览器看到的 UI 地址"与"REST 入口地址";注意 DSPACE_REST_HOST/PORT 指向的是宿主入口 192.168.1.200:8139 而非后端内部地址——浏览器侧发起的 API 请求必须走统一入口,SSR 服务端渲染则经 DSPACE_REST_SSRBASEURL 直连后端内部 8080,两条路径分离是官方 SSR 架构的关键。
  6. dspace-proxy:nginx 只读挂载单文件配置(见第五节),全栈唯一端口映射 8139:80。

五、反向代理统一入口

nginx/dspace.conf 全文(照抄在跑配置):

server {
    listen 80;
    server_name _;

    client_max_body_size 100M;

    location /server/ {
        proxy_pass http://dspace-10.1-backend:8080/server/;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
    }

    location / {
        proxy_pass http://dspace-10.1-ui:4000;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

要点:

  • 一个域名/端口承载两个命名空间:/server/ 前缀给 REST 后端,其余全部给 Angular UI——这正是 DSpace 官方推荐的"同域入口"形态,前端不需要跨域配置,Cookie(XSRF/会话)天然同域;
  • client_max_body_size 100M 放开大文件上传上限(默认 1M 会让比特流上传直接 413);
  • UI 段带 Upgrade/Connection 头,支持 Angular 的 websocket 通道;
  • 后端侧配套 proxies.trusted.ipranges: 10.89.58,信任本网段的 X-Forwarded-For,保证统计与审计记录真实来源 IP。

六、启动与初始化实录

6.1 拉起与状态

docker compose up -d
docker compose ps

实测回显:

NAME                  IMAGE                                              COMMAND                  SERVICE          CREATED          STATUS          PORTS
dspace-10.1-backend   docker.io/dspace/dspace:dspace-10.1                "/bin/bash -c 'while…"   dspace           40 minutes ago   Up 39 minutes   8000/tcp, 8080/tcp
dspace-10.1-db        docker.io/postgres:15                              "docker-entrypoint.s…"   dspacedb         57 minutes ago   Up 57 minutes   5432/tcp
dspace-10.1-proxy     docker.io/nginx:1.27-alpine                        "/docker-entrypoint.…"   dspace-proxy     57 minutes ago   Up 57 minutes   0.0.0.0:8139->80/tcp, [::]:8139->80/tcp
dspace-10.1-solr      docker.io/dspace/dspace-solr:dspace-10.1           "/bin/bash -c 'init-…"   dspacesolr       57 minutes ago   Up 57 minutes   8983/tcp
dspace-10.1-ui        docker.io/dspace/dspace-angular:dspace-10.1-dist   "pm2-runtime start d…"   dspace-angular   57 minutes ago   Up 57 minutes   4000/tcp

宿主监听确认(ss -lntp | grep 8139):

LISTEN 0      4096         0.0.0.0:8139       0.0.0.0:*
LISTEN 0      4096            [::]:8139          [::]:*

6.2 数据库迁移(entrypoint 自动执行)

后端日志开头实录:

Database URL: jdbc:postgresql://dspace-10.1-db:5432/dspace
Migrating database to latest version... (Check dspace logs for details)
Done.
Picked up JAVA_TOOL_OPTIONS: -Xms256m -Xmx512m
2026-11-01 13:07:51,651 INFO  unknown unknown org.hibernate.validator.internal.util.Version @ HV000001: Hibernate Validator 8.0.5.Final

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::               (v3.5.16)

迁移结果核验(连库数表):

64

即 dspace database migrate 建出 64 张核心表(元数据值、DspaceObject、组/策略、工作流、社区/收藏层级等)。

6.3 创建管理员账号

迁移只建表不建账号,管理员用官方 CLI create-administrator 创建。交互提示流实录(依次输入邮箱、名、姓、确认 y、两次口令):

Creating an initial administrator account
E-mail address: First name: Last name: Is the above data correct? (y or n): Password will not display on screen.
Password:
Again to confirm:
Administrator account created

本例创建 admin@dspace.local(口令 q1w2e3r4,演示用);为验证可重复性又建了第二账号 demo-admin@dspace.local,随后经 REST 登录实测 HTTP 200。库内账号核验:

admin@dspace.local
demo-admin@dspace.local

⚠️ 该命令要求真实终端(TTY),无终端直接管道喂输入会报 Exception: Cannot invoke "java.io.Console.readLine()" because "console" is null,排障见第十节问题 1。

6.4 Solr core 核验

检索栈数据目录实测清单:

audit
authority
oai
qaevent
search
statistics
suggestion

7 个 core 与第四节预建清单一一对应。

七、JVM 堆治理(256–512MB)

官方后端启动默认不设堆上限、CLI 启动器(ScriptLauncher)自带 -Xmx2000m,小内存主机必须显式治理。修改位置就是 compose 后端服务的 environment:

      JAVA_TOOL_OPTIONS: -Xms256m -Xmx512m

生效验证一:后端日志首行出现拾取记录(6.2 节实录):

Picked up JAVA_TOOL_OPTIONS: -Xms256m -Xmx512m

生效验证二:进程级 jps -lv 实测回显(主进程 pid 1):

1 server-boot.jar -Xms256m -Xmx512m

同机各进程堆预算一览(实测):后端 256–512m、前端 Node --max-old-space-size=512、Solr MEM=256m、PostgreSQL 默认——整栈 2GB 内存主机可稳定运行。

💡 技术拓展:JAVA_TOOL_OPTIONS 与 JAVA_OPTS 取舍——前者是 JVM 原生识别的通用变量(任何 java 启动都会拾取并打印 Picked up 行),对官方镜像里"entrypoint 直接 java -jar"的形态最稳;JAVA_OPTS 只有启动脚本引用它时才生效。DSpace CLI 那条 -Xmx2000m 来自安装目录 bin/dspace 脚本自身,与后端堆相互独立:跑 database migrate、index-discovery 等大任务时若受 2GB 上限限制,可在执行环境单独覆盖 CLI 的堆参数,不必放大常驻后端。

八、端到端验证

  1. UI 首页:
curl -sI http://127.0.0.1:8139/
HTTP/1.1 200 OK
Server: nginx/1.27.5
Content-Type: text/html; charset=utf-8
Content-Length: 114298
X-Powered-By: Express
RateLimit-Policy: 500;w=60
RateLimit-Limit: 500

页面标题实测:<title>DSpace Repository :: Home</title>。

  1. REST 入口:
curl -s http://127.0.0.1:8139/server/api
{
  "dspaceUI" : "http://192.168.1.200:8139",
  "dspaceName" : "DSpace via local.cfg",
  "dspaceServer" : "http://192.168.1.200:8139/server",
  "dspaceVersion" : "DSpace 10.1",
  "type" : "root",
  ...
}

dspaceVersion: DSpace 10.1 与第二节版本线核对一致;dspaceName 显示 local.cfg 生效值,其优先级链实验见配置篇。

  1. 登录链路(细节见 API 篇):POST /server/api/authn/login 实测 HTTP/1.1 200 并返回 Authorization: Bearer <JWT> 响应头。

九、持久化、升级与日常运维

持久化三卷:pgdata(结构化数据)、assetstore(比特流文件)、solr_data(索引与统计)。备份策略:pg_dump + assetstore 打包为权威组合,Solr 索引可全量重建(index-discovery CLI)不必纳入备份。

一个易踩的坑:配置覆写文件 local.cfg 若直接写入运行实例的可写层,重建(recreate)即丢失——优先级实验实测:删除环境变量并重建后,dspaceName 立刻回落到 dspace.cfg 出厂值 "DSpace at My University"。生产形态应把 local.cfg 以挂载方式固化(见配置篇)。

升级流程:改三处 dspace-10.x 标签 → docker compose up -d(自动重建)→ 后端 entrypoint 自动 database migrate → 验证 6.2/第八节。跨大版本(如 9→10)先读官方升级说明并全量备份。

日常运维命令速查:

操作命令
查看栈状态docker compose ps
跟踪后端日志docker compose logs -f dspace
重启后端docker compose restart dspace
进入后端执行 CLIdocker compose exec dspace /dspace/bin/dspace <command>
停栈(保留数据)docker compose down
连库docker compose exec dspacedb psql -U dspace -d dspace

十、排障实录

问题 1:create-administrator 无终端即崩 现象:管道喂输入执行 /dspace/bin/dspace create-administrator,回显:

Creating an initial administrator account
E-mail address: Exception: Cannot invoke "java.io.Console.readLine()" because "console" is null
java.lang.NullPointerException: Cannot invoke "java.io.Console.readLine()" because "console" is null
	at org.dspace.administer.CreateAdministrator.negotiateAdministratorDetails(CreateAdministrator.java:159)

原因:该 CLI 用 System.console() 读交互输入,非 TTY 环境 console 为 null。解决:给命令分配伪终端。实测方案(宿主执行,成功回显见 6.3):

printf 'admin@dspace.local\nDemo\nAdmin\ny\nq1w2e3r4\nq1w2e3r4\n' | \
  docker compose exec -T dspace bash -c \
  "script -qec '/dspace/bin/dspace create-administrator' /dev/null"

注意提示顺序是 邮箱→名→姓→确认(y/n)→口令→重复口令,确认项漏填 y 会整体重来(实测循环两轮)。

问题 2:登录 403,不是 401 不带 X-XSRF-TOKEN 头直接 POST 登录,实测 HTTP 403(凭据正确也一样)。DSpace 的 CSRF 防护要求"Cookie + 同名请求头"成对出现,先 GET 任意 API 拿 DSPACE-XSRF-COOKIE,再原样回填请求头。完整流程与回显见 API 篇。

问题 3:重建后配置"回退" 即第九节 local.cfg 丢失坑:可写层改动不随卷持久化,up -d --force-recreate 后一切覆写消失。表现是"配置改过又变回去了",先查改动落在哪一层(env/挂载卷/可写层),优先级链实验方法见配置篇。

问题 4:默认配置全指向 localhost 出厂 dspace.cfg 实测关键项:

dspace.server.url = http://localhost:8080/server
dspace.ui.url = http://localhost:4000
db.url = jdbc:postgresql://localhost:5432/dspace
solr.server = http://localhost:8983/solr

多服务编排下这些 localhost 全部无效(各自指自己),必须用 db__P__url、solr__P__server、dspace__P__server__P__url 等环境变量覆盖——这就是第四节 env 清单的由来。

问题 5:Solr core 缺失导致后端起不来 官方 dspace-solr 镜像无自动建 core 逻辑,直接起裸 Solr 会让后端在 statistics/search 等 core 上报错。解法即第四节 entrypoint 的 precreate-core 预建清单。

问题 6:找 OpenAPI 契约 404 GET /server/v3/api-docs 实测 404:

{"type":"about:blank","title":"Not Found","status":404,"detail":"No static resource v3/api-docs.","instance":"/server/v3/api-docs"}

10.1 后端不发布 OpenAPI 端点;API 契约就是 HAL 超媒体本身,从 /server/api 根逐链接发现(见 API 篇)。

十一、部署检查清单

  • docker compose ps 五服务全部 Up,仅 proxy 映射宿主端口
  • ss -lntp 宿主监听 8139
  • 后端日志出现 Migrating database to latest version... Done. 且 Spring Boot banner 正常
  • 数据库 64 表就位;create-administrator 成功且登录返回 200
  • Solr 数据目录 7 core 齐全
  • jps -lv 后端进程带 -Xms256m -Xmx512m
  • UI 首页 200、/server/api 回显 dspaceVersion: DSpace 10.1
  • proxies.trusted.ipranges 与专用网段一致
  • 三个命名卷 + local.cfg 挂载固化
  • 生产加固:口令更换、HTTPS、备份计划

十二、参考链接

  1. DSpace/DSpace GitHub(Releases 版本线取证,查询日期 2026-11-01):https://github.com/DSpace/DSpace/releases
  2. DSpace 官方文档 DSDOC10x(Docker/安装章节,查询日期 2026-11-01):https://wiki.lyrasis.org/display/DSDOC10x
  3. Docker Hub dspace 命名空间(镜像标签口径,查询日期 2026-11-01):https://hub.docker.com/u/dspace
  4. 站内:《DSpace 介绍与选型指南》
  5. 站内:《DSpace 配置参数详解(env/local.cfg/dspace.cfg 三层优先级链与关键项)》
  6. 站内:《DSpace REST API 使用详解(HAL 超媒体认证、CRUD 与检索实测)》
  7. 站内同类部署实录对照:《EPrints 3.4.7 Ubuntu 22.04 安装部署指南》
DSpace 10.1 Docker Compose 部署指南 - Quzuo