Apache JSPWiki 2.12.5 Docker Compose 部署指南

使用 Docker Compose 部署 Apache JSPWiki 2.12.5:自建镜像、Compose 编排、数据卷持久化、等价 docker run、日常运维与 FAQ,全程实测回显。

Apache JSPWikiApache JSPWiki2026/10/13

Apache JSPWiki 2.12.5 Docker Compose 部署指南

目标:用 Docker Compose 一键部署 Apache JSPWiki 2.12.5,实现镜像自建、数据持久化与日常运维闭环。已在 Docker 29.8.0 + Compose v5.5.1 + JSPWiki 2.12.5 环境实测通过。

一、环境信息

1.1 版本与镜像选型

JSPWiki 2.12.x 基于 javax.servlet 命名空间,镜像内必须使用 Tomcat 9(Tomcat 10+ 为 jakarta 命名空间,不兼容,见《Ubuntu 22.04 安装 Apache JSPWiki 2.12.5 指南》版本选型一节)。

Apache 官方没有在 Docker Hub 维护与 2.12.5 对应的发行镜像,Docker Hub 上的第三方 JSPWiki 镜像版本陈旧、无法校验构建内容。本方案选择自建镜像:ubuntu:22.04 基础镜像 + APT 安装 OpenJDK 17 与 Tomcat 9 + 复制官方 WAR(sha512 校验通过后 COPY 进镜像),与"从 0 到 1 安装"篇的服务器部署完全同构,便于口径统一。

1.2 实测环境

项实测值
Docker Engine29.8.0
Docker ComposeDocker Compose version v5.5.1
基础镜像ubuntu:22.04
JSPWiki2.12.5 官方 WAR(36752001 字节,sha512 校验通过)
镜像内组件OpenJDK 17(APT)+ Tomcat 9.0.58(APT)
数据卷/opt/jspwiki/data/jspwiki → /var/lib/jspwiki
对外端口8080
管理账号admin / q1w2e3r4

版本确认命令与实测输出:

docker compose version
docker version --format '{{.Server.Version}}'
Docker Compose version v5.5.1
29.8.0

1.3 部署架构

  • 镜像:jspwiki:2.12.5(自建,含 JDK 17 + Tomcat 9 + 官方 WAR)
  • 配置:jspwiki-custom.properties 放在数据卷内,通过 JVM 参数 -Djspwiki.custom.config=/var/lib/jspwiki/jspwiki-custom.properties 指定(配置加载优先级见《Apache JSPWiki 2.12.5 配置参数详解》)
  • 数据:页面、索引、用户库全部落在数据卷 /var/lib/jspwiki,重建容器不丢数据
  • 运行用户:镜像内 USER tomcat(uid/gid 999),数据卷须归 999 属主

二、获取 WAR 包并构建镜像

2.1 准备构建目录

mkdir -p /opt/jspwiki && cd /opt/jspwiki
curl -fsSLO https://dlcdn.apache.org/jspwiki/2.12.5/binaries/webapp/JSPWiki.war
curl -fsSLO https://dlcdn.apache.org/jspwiki/2.12.5/binaries/webapp/JSPWiki.war.sha512
cat JSPWiki.war.sha512
sha512sum JSPWiki.war

实测输出(两个哈希一致即校验通过):

b9436587cca6a29c1e2fb56496d304f977e22c51f1e391bf83724b7ff106e149f55573cfba93fe2e03773f052d206f85ebf6e0cac7fabccce2ed29de13548d4f
b9436587cca6a29c1e2fb56496d304f977e22c51f1e391bf83724b7ff106e149f55573cfba93fe2e03773f052d206f85ebf6e0cac7fabccce2ed29de13548d4f  JSPWiki.war

2.2 编写 Dockerfile

在 /opt/jspwiki/Dockerfile 写入:

FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update \
 && apt-get install -y --no-install-recommends openjdk-17-jdk-headless tomcat9 \
 && rm -rf /var/lib/apt/lists/*

COPY JSPWiki.war /var/lib/tomcat9/webapps/JSPWiki.war

RUN mkdir -p /var/lib/tomcat /var/lib/jspwiki/pages /var/lib/jspwiki/work \
 && chown -R tomcat:tomcat /var/lib/tomcat /var/lib/jspwiki

ENV CATALINA_HOME=/usr/share/tomcat9 \
    CATALINA_BASE=/var/lib/tomcat9 \
    CATALINA_TMPDIR=/tmp \
    JAVA_OPTS="-Djava.awt.headless=true -Xms256m -Xmx512m"

EXPOSE 8080

WORKDIR /var/lib/tomcat9

USER tomcat

CMD ["/usr/share/tomcat9/bin/catalina.sh", "run"]

要点:

  • mkdir /var/lib/tomcat:JSPWiki 默认页面目录 ${user.home}/jspwiki-files 指向 tomcat 用户家目录,目录不存在会导致引擎初始化失败(详见《Ubuntu 22.04 安装 Apache JSPWiki 2.12.5 指南》FAQ Q1)。
  • JAVA_OPTS 堆限制 256–512MB;catalina.sh run 前台运行,适配容器日志采集。
  • USER tomcat 非特权运行,数据卷须 chown 为 uid 999。

2.3 构建镜像

docker build -t jspwiki:2.12.5 .

实测输出(尾部):

#10 exporting manifest list sha256:e4e2cdd428a175c5f0199f6efa254710c6052a80ca4add1675b57e0afa44bc20 0.0s done
#10 naming to docker.io/library/jspwiki:2.12.5 done
#10 unpacking to docker.io/library/jspwiki:2.12.5 0.0s done
#10 DONE 0.2s
docker compose images

实测输出:

CONTAINER           REPOSITORY          TAG                 PLATFORM            IMAGE ID            SIZE                CREATED
jspwiki             jspwiki             2.12.5              linux/amd64         29f6cdfca6fe        947MB               28 minutes ago

三、编写 Compose 文件与数据准备

3.1 目录结构

/opt/jspwiki/
├── Dockerfile
├── JSPWiki.war
├── docker-compose.yml
└── data/jspwiki/                  # 数据卷(挂载到 /var/lib/jspwiki)
    ├── jspwiki-custom.properties  # 覆盖配置
    ├── pages/                     # 页面存储
    ├── work/                      # 搜索索引/缓存
    ├── userdatabase.xml           # 用户库(向导初始化后生成)
    └── groupdatabase.xml          # 组库(向导初始化后生成)

3.2 编写 docker-compose.yml

services:
  jspwiki:
    image: jspwiki:2.12.5
    container_name: jspwiki
    ports:
      - "8080:8080"
    environment:
      JAVA_OPTS: "-Djava.awt.headless=true -Xms256m -Xmx512m -Djspwiki.custom.config=/var/lib/jspwiki/jspwiki-custom.properties"
    volumes:
      - ./data/jspwiki:/var/lib/jspwiki
    restart: unless-stopped

3.3 预置覆盖配置并准备数据目录

mkdir -p data/jspwiki/pages data/jspwiki/work
cat > data/jspwiki/jspwiki-custom.properties <<'EOF'
jspwiki.applicationName=MyWiki
jspwiki.workDir=/var/lib/jspwiki/work
jspwiki.fileSystemProvider.pageDir=/var/lib/jspwiki/pages
jspwiki.basicAttachmentProvider.storageDir=/var/lib/jspwiki/pages
jspwiki.pageProvider=VersioningFileProvider
jspwiki.xmlUserDatabaseFile=/var/lib/jspwiki/userdatabase.xml
jspwiki.xmlGroupDatabaseFile=/var/lib/jspwiki/groupdatabase.xml
EOF
chown -R 999:999 data

说明:

  • -Djspwiki.custom.config 是 JSPWiki 官方的覆盖配置入口(优先级最高的自定义配置来源之一),指向数据卷内的文件,配置随数据卷持久化,重建容器不丢。
  • jspwiki.xmlUserDatabaseFile 把用户库从 WAR 内的 WEB-INF/userdatabase.xml 迁到数据卷,向导创建的 admin 账号直接落在持久化目录。
  • chown -R 999:999:镜像内 USER tomcat 的 uid/gid 为 999,属主不对会导致启动后 404(FAQ Q2)。

四、启动部署与初始化

4.1 启动 Compose 栈

docker compose up -d

实测输出:

 Container jspwiki Starting
 Container jspwiki Started
docker compose ps

实测输出:

NAME      IMAGE            COMMAND                  SERVICE   CREATED          STATUS        PORTS
jspwiki   jspwiki:2.12.5   "/usr/share/tomcat9/…"   jspwiki   2 seconds ago   Up 1 second   0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp

首次启动含 Tomcat 初始化与 WAR 解包,约 30–60 秒后可访问。验证:

wget -q -S -O /dev/null http://localhost:8080/JSPWiki/ 2>&1 | head -2

实测输出:

  HTTP/1.1 200
  Set-Cookie: JSESSIONID=4AAF897B552B07CD1D69D5CC4252F9C9; Path=/JSPWiki; HttpOnly

4.2 初始化 admin 账号

页面、工作目录、用户库位置已由覆盖配置预置,首次初始化只需通过安装向导创建 admin 账号与 Admin 组(浏览器访问 http://<服务器IP>:8080/JSPWiki/Install.jsp 点 Configure,或用下面的 curl 自动化,效果等价):

rm -f /tmp/w.jar
TOKEN=$(curl -s -c /tmp/w.jar http://localhost:8080/JSPWiki/Install.jsp | grep -oE "X-XSRF-TOKEN\" id=\"X-XSRF-TOKEN\" value=\"[a-f0-9-]+" | grep -oE "[a-f0-9-]{20,}" | head -1)
curl -s -b /tmp/w.jar -X POST http://localhost:8080/JSPWiki/Install.jsp \
  --data-urlencode "X-XSRF-TOKEN=$TOKEN" \
  --data-urlencode "jspwiki.applicationName=MyWiki" \
  --data-urlencode "jspwiki.fileSystemProvider.pageDir=/var/lib/jspwiki/pages" \
  --data-urlencode "jspwiki.workDir=/var/lib/jspwiki/work" \
  --data-urlencode "submit=Configure!" -o /tmp/wiz.html
grep -oE "account's id is admin and the password is [A-Za-z0-9]+" /tmp/wiz.html

实测输出(随机密码每次不同,务必记录):

account's id is admin and the password is gFZpsyVh

⚠️ 与服务器部署不同:本方案的覆盖配置在数据卷内且经 -Djspwiki.custom.config 加载,向导写到工作目录的 jspwiki-custom.properties 无需归位,忽略其提示即可;重要的是 admin 账号已写入数据卷内的 userdatabase.xml。

4.3 修改 admin 密码并创建测试页

将 admin 密码改为 q1w2e3r4(把命令中的随机密码替换为上一步记录值),流程与命令同《Ubuntu 22.04 安装 Apache JSPWiki 2.12.5 指南》方案 B 第(3)步,实测输出一致:

login: 302
saveProfile: 302

创建测试页 ComposeTest(内容 Docker Compose deployment verification page for JSPWiki 2.12.5.),保存实测输出:

savepage: 200

数据落盘确认(数据卷内):

docker exec jspwiki bash -c 'find /var/lib/jspwiki/pages -type f | sort'

实测输出:

/var/lib/jspwiki/pages/ComposeTest.txt
/var/lib/jspwiki/pages/OLD/ComposeTest/page.properties
docker exec jspwiki ls -la /var/lib/jspwiki/ | grep -vE "^total|^d.*\.$"

实测输出:

-rw-r----- 1 tomcat tomcat  260 Oct 11 13:44 groupdatabase.xml
-rw-r--r-- 1 tomcat tomcat  363 Oct 11 13:42 jspwiki-custom.properties
drwxr-xr-x 3 tomcat tomcat 4096 Oct 11 13:45 pages
-rw-r----- 1 tomcat tomcat  394 Oct 11 13:45 userdatabase.xml
-rw-r----- 1 tomcat tomcat  377 Oct 11 13:44 userdatabase.xml.old
drwxr-xr-x 4 tomcat tomcat 4096 Oct 11 13:45 work

页面、用户库、组库均已持久化在数据卷。

五、持久化与重启验证

docker compose restart

实测输出:

 Container jspwiki Restarting
 Container jspwiki Started

等待约 25 秒后验证(页面与账号均来自数据卷):

wget -q -S -O /dev/null http://localhost:8080/JSPWiki/ 2>&1 | head -2

实测输出:

  HTTP/1.1 200
  Set-Cookie: JSESSIONID=07BAE116516D7B3BAA597D3556A9EF1A; Path=/JSPWiki; HttpOnly
  • 重建容器(docker compose down && docker compose up -d)后 ComposeTest 页面内容仍可访问;
  • admin 以 q1w2e3r4 重新登录成功,页头身份显示 wikiUserName" content="Administrator";
  • docker compose down 只删除运行实例,不动数据卷,实测输出:
 Network jspwiki_default Removing
 Network jspwiki_default Removed

六、等价 docker run 部署

不使用 Compose 时,以下单条 docker run 与上面的 Compose 定义完全等价(独立数据目录、端口 8081):

mkdir -p /opt/run-data/pages /opt/run-data/work
cp /opt/jspwiki/data/jspwiki/jspwiki-custom.properties /opt/run-data/
chown -R 999:999 /opt/run-data
docker run -d --name jspwiki-run -p 8081:8080 \
  -e JAVA_OPTS="-Djava.awt.headless=true -Xms256m -Xmx512m -Djspwiki.custom.config=/var/lib/jspwiki/jspwiki-custom.properties" \
  -v /opt/run-data:/var/lib/jspwiki \
  jspwiki:2.12.5

实测输出:

725727d47e37404e5da5752be5a7387fe87958e04910265fcac027ca8fbf784a
wget -q -S -O /dev/null http://localhost:8081/JSPWiki/ 2>&1 | head -2

实测输出:

  HTTP/1.1 200
  Set-Cookie: JSESSIONID=4AAF897B552B07CD1D69D5CC4252F9C9; Path=/JSPWiki; HttpOnly
维度docker runDocker Compose
参数管理全部写在命令行docker-compose.yml 版本化
启停docker start/stop/rm jspwiki-rundocker compose up/down/restart
多环境复制手工改命令拷贝 yml + data 目录
适用场景单次验证、临时实例生产长期运行

七、日常运维

7.1 日志

docker compose logs --tail 2 jspwiki

实测输出:

jspwiki  |  [WARN ] 2026-10-11 19:08:25.907 [http-nio-8080-exec-1] o.a.w.u.PropertyReader - sys:java.io.tmpdir referenced on appender.rolling.fileName (${sys:java.io.tmpdir}/jspwiki.log) but not found on System props or env
jspwiki  |  [INFO ] 2026-10-11 19:08:25.907 [http-nio-8080-exec-1] o.a.w.u.PropertyReader - jspwiki.workDir is already set to: /var/lib/jspwiki/work

💡 第一条 WARN 无害:默认日志配置里 RollingFile appender 挂在 ${sys:java.io.tmpdir}/jspwiki.log,但 logger 只挂了控制台输出,文件日志默认未启用,故该变量未解析。容器场景下日志走 docker logs 即可;如需文件日志见《Apache JSPWiki 2.12.5 配置参数详解》日志参数一节。

排查启动故障:

docker logs jspwiki 2>&1 | grep -cE "ERROR|FATAL"

实测输出(正常部署应为 0):

0

7.2 状态与端口

docker compose ps
docker port jspwiki

实测输出:

NAME      IMAGE            COMMAND                  SERVICE   CREATED          STATUS        PORTS
jspwiki   jspwiki:2.12.5   "/usr/share/tomcat9/…"   jspwiki   21 minutes ago   Up 18 minutes   0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
8080/tcp -> 0.0.0.0:8080
8080/tcp -> [::]:8080

7.3 备份与恢复

tar czf /opt/jspwiki-backup-$(date +%Y%m%d).tar.gz -C /opt/jspwiki data

恢复:停栈(docker compose down),解包覆盖 data/,chown -R 999:999 data,再 up -d。

7.4 升级版本

cd /opt/jspwiki
curl -fsSLO https://dlcdn.apache.org/jspwiki/<新版本号>/binaries/webapp/JSPWiki.war
sha512sum JSPWiki.war && cat JSPWiki.war.sha512   # 校验
docker build -t jspwiki:<新版本号> .
sed -i 's|image: jspwiki:.*|image: jspwiki:<新版本号>|' docker-compose.yml
docker compose up -d

数据卷(页面/用户库/配置)不动;跨大版本升级(2.12 → 3.0)需先评估 jakarta 命名空间与容器版本变化。

7.5 镜像离线迁移(docker save / load)

无法访问 Docker Hub 的环境,可在有网机器构建后导出镜像文件,在目标机导入:

docker save jspwiki:2.12.5 -o jspwiki-2.12.5-image.tar
# 目标机
docker load -i jspwiki-2.12.5-image.tar

docker load 成功回显样式(以 ubuntu:22.04 实测为例):

Loaded image: ubuntu:22.04

八、常见问题(FAQ)

Q1:docker compose up -d 后访问 404?

按顺序排查:

  1. docker logs jspwiki 2>&1 | grep -E "ERROR|FATAL":出现 No permission to write to work directory → 数据卷属主不对,执行 chown -R 999:999 data 后 docker compose restart;
  2. 确认数据卷内有 jspwiki-custom.properties 且 JAVA_OPTS 带 -Djspwiki.custom.config=/var/lib/jspwiki/jspwiki-custom.properties;
  3. 首次启动 WAR 解包需要 30–60 秒,过早访问会 404,稍候重试。

Q2:日志报 Permission denied,无法写 /var/lib/jspwiki/...?

镜像以 uid/gid 999(tomcat)运行,宿主机数据目录须归 999:

chown -R 999:999 /opt/jspwiki/data
docker compose restart

Q3:端口 8080 被占用?

修改 docker-compose.yml 端口映射左侧宿主端口即可,如 "18080:8080",访问 http://<服务器IP>:18080/JSPWiki/。

Q4:为什么不用 Docker Hub 现成镜像?

Apache 官方未发布与 2.12.5 对应的发行镜像;第三方镜像版本与构建内容不可控。自建镜像基于 ubuntu:22.04 + APT + 官方 WAR(sha512 校验),与服务器部署同构,升级与审计路径清晰。完全离线的环境用 7.5 的 save/load 迁移。

Q5:admin 随机密码丢失?

数据卷用户库中删除 admin 条目后重新提交向导即可重建(会生成新的随机密码):

docker compose down
sed -i '/loginName="admin"/d' data/jspwiki/userdatabase.xml
docker compose up -d
# 重新执行 4.2 向导 curl,记录新随机密码

Q6:docker logs 里反复出现 sys:java.io.tmpdir referenced on appender.rolling.fileName ... not found?

无害告警(详见 7.1 说明)。要求消除时,在数据卷 jspwiki-custom.properties 中把文件日志路径写死并挂载 logger(两行):

appender.rolling.fileName=/var/lib/jspwiki/jspwiki.log
logger.jspwiki.appenderRef.rolling.ref = RollingFile

重启后日志文件生成于数据卷内(宿主机 data/jspwiki/jspwiki.log),随卷持久化。

九、参考链接