Apache Archiva 2.2.10 Docker Compose 部署指南

Apache Archiva 2.2.10 Docker Compose 部署指南:基于 eclipse-temurin:8-jdk 自建 archiva:2.2.10 镜像(COPY 发行包完全离线构建,wrapper.conf 内置 256-512MB 堆),Compose 编排单服务,挂载 data/repositories/logs 三个目录持久化,端口 8080 映射,REST 初始化管理员并验证重启持久化,全程命令与回显实测

Apache ArchivaArchiva2026/10/13

Apache Archiva 2.2.10 Docker Compose 部署指南

目标:使用 Docker Compose 编排 Apache Archiva 2.2.10 仓库管理服务:基于 eclipse-temurin:8-jdk 自建 archiva:2.2.10 镜像(COPY 方式注入官方发行包,构建完全离线),挂载 data / repositories / logs 三个目录落盘持久化,端口 8080 映射,JVM 堆限定 256-512MB,重启后账号与仓库数据不丢。全程命令与回显均为实际执行结果。

一、环境信息

  • Docker:29.8.1(实测环境,docker version Server Version)
  • Docker Compose:v2.5.1(docker compose 子命令)
  • Archiva 镜像:自建 archiva:2.2.10(基于 eclipse-temurin:8-jdk,内含 Archiva 2.2.10 独立发行包,构建后镜像 461MB)
  • 服务:archiva(Web 控制台 + REST API + 仓库代理下载,单服务单进程)
  • 映射端口:8080(HTTP)
  • 挂载目录:./data → /opt/archiva/data(Derby 元数据)、./repositories → /opt/archiva/repositories(制品存储)、./logs → /opt/archiva/logs
  • 管理账号:admin / q1w2e3r4(REST 初始化)

💡 说明:Archiva 项目没有官方维护的镜像;archive.apache.org 归档站只有 tar.gz/war 制品。自建镜像的价值在于版本固定、可离线分发,且与《安装指南》的二进制部署使用同一份发行包,行为完全一致。

二、镜像选型说明

镜像基础说明
archiva:2.2.10(自建)eclipse-temurin:8-jdk本指南采用:官方 tar.gz 打进镜像,wrapper.conf 出厂即改好 256-512MB 堆,开箱可用
仅用 eclipse-temurin:8-jdk + 挂载发行包官方基础镜像不做镜像,把 tar.gz 解压目录整体挂进运行命令;适合快速试用,但配置改动都在宿主机命令里,不易留档

关键差异:两者运行时行为相同(都是同一发行包 + JSW wrapper console 前台启动)。自建镜像把「解压、改堆」固化进构建,交付物就是一个镜像文件,推荐主线方案。

三、前置条件

  • 装有 Docker 与 Docker Compose v2 的服务器,root 权限。
  • 已从归档站取得 apache-archiva-2.2.10-bin.tar.gz(约 68MB,下载与 SHA256 校验方式见《Apache Archiva 2.2.10 安装指南》4.2 节,本文不再重复校验输出)。
  • 宿主机 8080 端口空闲(ss -tlnp | grep 8080 应无输出)。

四、部署步骤

4.1 创建目录结构

mkdir -p archiva-compose && cd archiva-compose
cp /opt/apache-archiva-2.2.10-bin.tar.gz .
ls -l
-rw-r--r-- 1 root root 68419100 Mar 16  2023 apache-archiva-2.2.10-bin.tar.gz

💡 发行包与 Dockerfile 放同一目录,后面用 COPY 注入镜像:构建期不访问外网,秒级完成,也规避了在构建步骤里直连归档站下载(实测该方式长时间无进展,见 9.1)。

4.2 编写自建镜像的 Dockerfile

cat > Dockerfile <<'EOF'
FROM eclipse-temurin:8-jdk

# Apache Archiva 2.2.10 发行包(与 Dockerfile 同目录提前放好,构建完全离线)
COPY apache-archiva-2.2.10-bin.tar.gz /tmp/

RUN cd /tmp \
    && tar -xzf apache-archiva-2.2.10-bin.tar.gz \
    && mv apache-archiva-2.2.10 archiva \
    && rm -f apache-archiva-2.2.10-bin.tar.gz \
    && mv /tmp/archiva /opt/archiva \
    && sed -i "s/^wrapper.java.initmemory=.*/wrapper.java.initmemory=256/" /opt/archiva/conf/wrapper.conf \
    && sed -i "s/^wrapper.java.maxmemory=.*/wrapper.java.maxmemory=512/" /opt/archiva/conf/wrapper.conf

WORKDIR /opt/archiva
EXPOSE 8080
CMD ["./bin/archiva", "console"]
EOF
指令说明
FROM eclipse-temurin:8-jdkArchiva 2.2.10 基于 Jetty 8 + 老版 JSP 栈,需 JDK 8(JDK 11+ 未适配);选 8-jdk,镜像内自带 jps
COPY ... /tmp/把已下载校验好的发行包带进构建,构建过程零外网依赖
sed wrapper.conf出厂堆 512/512,构建期固化为 256/512(生效验证见 4.6)
CMD ./bin/archiva consolewrapper console 模式前台运行,日志输出交给 docker,进程退出即服务退出

构建镜像:

docker build -t archiva:2.2.10 .
#8 [4/4] WORKDIR /opt/archiva
#8 DONE 0.9s
#9 exporting to image
#9 exporting layers 0.5s done
#9 writing image sha256:2cededdfbd5807599905c3c7a9d10de3716a54c985a6f9468c176c3e1bdc5a08 done
#9 naming to docker.io/library/archiva:2.2.10 done
#9 DONE 0.6s
docker images --format "{{.Repository}}:{{.Tag}}  {{.Size}}" | grep archiva
archiva:2.2.10  461MB

解读:461MB = temurin JDK 基础(约 400MB)+ Archiva 发行包解压(约 260MB,与基础层有去重);镜像 ID 每次构建不同,以本机输出为准。

4.3 编写 docker-compose.yml

cat > docker-compose.yml <<'EOF'
version: "3.8"

services:
  archiva:
    image: archiva:2.2.10
    container_name: archiva-server
    restart: unless-stopped
    mem_limit: 1g
    ports:
      - "8080:8080"
    volumes:
      - ./data:/opt/archiva/data
      - ./repositories:/opt/archiva/repositories
      - ./logs:/opt/archiva/logs
EOF
配置项说明
container_name: archiva-server固定实例名,方便 docker exec / docker logs 操作
portsWeb 控制台、REST 与仓库下载共用 8080,一并映射
volumes三个目录挂载:Derby 元数据、制品存储、日志全部落盘宿主机
mem_limit: 1g实例内存上限;堆 256/512 + 永久代 128MB 的稳态占用约 430MB,1g 余量充足
restart: unless-stopped宿主机重启后自动拉起(docker 服务在运行时)

💡 v2 的 compose 会提示 the attribute version is obsolete, it will be ignored——仅提示,可删掉 version: "3.8" 行消除;本文保留与实测文件一致。

4.4 启动与状态确认

docker compose up -d
[+] Running 2/2
 ✔ Network archiva-compose_default  Created
 ✔ Container archiva-server         Started
docker compose ps
NAME             IMAGE            COMMAND                  SERVICE   CREATED         STATUS                  PORTS
archiva-server   archiva:2.2.10   "/__cacert_entrypoin…"   archiva   3 seconds ago   Up Less than a second   0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp

解读:COMMAND 显示 "/__cacert_entrypoin…" 是 temurin 基础镜像入口脚本,它再 exec 我们的 ./bin/archiva console。

启动日志(wrapper console 模式输出,节选):

docker logs archiva-server 2>&1 | tail -3
Running Apache Archiva...
Running Apache Archiva...
Removed stale pid file: /opt/archiva/logs/archiva.pid

首次启动含 Derby 建库,约 20-30 秒就绪。三个挂载目录随之生成:

ls data repositories logs
data:
databases  jcr  remotes

logs:
archiva-audit.log  archiva.log  archiva.pid  request-20261013.log  wrapper-20261013.log

repositories:
internal  repositories  snapshots

⚠️ repositories/ 下除 internal、snapshots 外还冒出一个嵌套的 repositories/repositories/(内含同名空目录):Archiva 首启用相对路径 ./repositories/internal 建仓,部分组件按错误基准目录解析产生的空目录,不影响使用;介意的话可删空目录,或经 REST 把仓库 location 改为绝对路径(见《安装指南》8.5 同款怪癖)。

4.5 初始化管理员

首次部署没有管理员账号,经 REST 初始化(Origin 头的地址端口要与访问 URL 一致,否则静默 403,见 9.2):

curl -s -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' \
  -H 'Origin: http://localhost:8080' \
  -d '{"username":"admin","password":"q1w2e3r4","confirmPassword":"q1w2e3r4","fullName":"Archiva Administrator","email":"admin@example.org","validated":true,"permanent":true}' \
  http://localhost:8080/restServices/redbackServices/userService/createAdminUser
true
curl -s -H 'Origin: http://localhost:8080' \
  http://localhost:8080/restServices/redbackServices/userService/isAdminUserExists
true

登录拿会话并列出内置仓库:

curl -s -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' \
  -H 'Origin: http://localhost:8080' -c /tmp/archiva-cookie.txt \
  -d '{"username":"admin","password":"q1w2e3r4"}' \
  http://localhost:8080/restServices/redbackServices/loginService/logIn | head -c 100
{"username":"admin","fullName":"Archiva Administrator","email":"admin@example.org","validated":true,"locked":false,"pass...
TOKEN=$(grep -oP '(?<="validationToken":")[^"]+' /tmp/login.json)
curl -s -b /tmp/archiva-cookie.txt -H 'Origin: http://localhost:8080' -H "X-XSRF-TOKEN: $TOKEN" \
  http://localhost:8080/restServices/archivaServices/managedRepositoriesService/getManagedRepositories \
  | python3 -c 'import json,sys; [print(r["id"],"->",r["location"]) for r in json.load(sys.stdin)]'
internal -> ./repositories/internal
snapshots -> ./repositories/snapshots

4.6 服务验证

Web 控制台:浏览器访问 http://<宿主机IP>:8080/,用 admin / q1w2e3r4 登录。命令行侧验证首页与免登录 ping 接口:

curl -s -o /dev/null -w "index:%{http_code}\n" http://localhost:8080/
curl -s http://localhost:8080/ | grep -oE '<title>[^<]*</title>'
curl -s -H 'Origin: http://localhost:8080' \
  http://localhost:8080/restServices/archivaServices/pingService/ping
index:200
<title>Apache Archiva</title>
Yeah Baby It rocks!

确认容器内 JVM 堆实际生效值(验证 4.2 的 wrapper.conf 固化已生效):

docker exec archiva-server jps -v | grep WrapperSimpleApp | grep -oE '\-Xms[0-9]+m \-Xmx[0-9]+m'
-Xms256m -Xmx512m

五、数据持久化说明

数据落盘位置说明
Derby 元数据宿主机 ./data/databases/仓库定义、用户、审计等,重启不丢
内容索引宿主机 ./data/jcr/、./data/remotes/jcr 会话工厂索引与远程下载缓存
制品存储宿主机 ./repositories/Maven 布局制品,重建实例不丢
运行日志宿主机 ./logs/archiva.log、wrapper-日期.log、request-日期.log、archiva-audit.log
配置镜像内 /opt/archiva/conf/未挂载;需定制见下方提示

验证持久化:重启后管理员与元数据依旧可用:

docker compose restart
sleep 25
docker compose ps
curl -s -H 'Origin: http://localhost:8080' \
  http://localhost:8080/restServices/redbackServices/userService/isAdminUserExists
 Container archiva-server  Restarting
 Container archiva-server  Started
NAME             IMAGE            COMMAND                  SERVICE   CREATED              STATUS                  PORTS
archiva-server   archiva:2.2.10   "/__cacert_entrypoin…"   archiva   About a minute ago   Up 25 seconds   0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
true

💡 说明:wrapper.conf 等配置已固化进镜像。若需在宿主机定制配置(如改端口),在 volumes: 中追加 - ./conf/wrapper.conf:/opt/archiva/conf/wrapper.conf 单文件挂载(先 docker exec archiva-server cat /opt/archiva/conf/wrapper.conf 取出厂底稿),改完 docker compose restart 生效。

六、环境变量表

Archiva 发行包没有业务语义的环境变量,行为全部由配置文件驱动。与运行相关的环境层面项如下:

环境变量/等价配置默认值说明
appserver.home / appserver.base(wrapper.conf 内置).安装根;镜像内 WORKDIR 即 /opt/archiva,无需改动
jetty.port(系统属性,出厂未设)8080需改端口时往 wrapper.conf 加 -Djetty.port=nnnn(见《配置参数详解》5.1)
JVM 堆出厂 512/512本文构建期固化为 256/512

💡 说明:Archiva 的 JVM 参数不走 JAVA_OPTS/JAVA_TOOL_OPTIONS 约定,而是读 conf/wrapper.conf 的 initmemory/maxmemory,所以 Compose 场景下改堆要么构建期 sed 固化(本文方式),要么单文件挂载覆盖 wrapper.conf。

七、配置参数说明

镜像内 /opt/archiva/conf/ 关键配置(出厂值与本文取值):

配置文件出厂值本文取值
JVM 初始/最大堆wrapper.conf 的 initmemory/maxmemory512 / 512256 / 512
监听端口jetty.xml(jetty.port 默认)80808080(映射即对外端口)
启动方式Dockerfile CMD—bin/archiva console(前台)
元数据库内嵌 Derbydata/databases挂载 ./data 持久化
本地仓库REST/控制台管理internal、snapshots挂载 ./repositories 持久化
实例内存上限compose mem_limit无1g

各配置项的完整含义、仓库调度与代理参数,见《Apache Archiva 2.2.10 配置参数详解》。

八、配置文件挂载

本方案默认不挂载配置(配置已固化进镜像),两种定制方式按需选择:

  • 单文件挂载(推荐):只挂 wrapper.conf 或 jetty.xml,保留镜像内其余出厂配置。挂载路径必须与镜像内路径一字不差:/opt/archiva/conf/wrapper.conf。
  • 重建镜像:团队内统一配置基线时,改 Dockerfile 里的 sed 步骤重新构建,交付物版本化。

修改宿主机文件后需 docker compose restart 生效;确认生效用:

docker exec archiva-server grep -E 'initmemory|maxmemory' /opt/archiva/conf/wrapper.conf
wrapper.java.initmemory=256
wrapper.java.maxmemory=512

九、常见问题

9.1 构建期 RUN wget 下载发行包长时间无进展

现象:Dockerfile 用 RUN wget ... https://archive.apache.org/... 方式构建,docker build 长时间停在下载步骤无输出(实测 18 分钟未完成),构建进程仍在。

定位:构建容器内直连归档站,受网络策略与归档站限速影响,wget -q 静默无进度反馈。

解决:按本文 4.2 的 COPY 方式——先在宿主机下载并校验好 tar.gz 放进构建目录,构建过程完全离线,实测数秒完成。

9.2 REST 请求静默 403(空响应体)

现象:curl http://127.0.0.1:8080/restServices/... 带 Origin: http://localhost:8080 仍返回空、状态 403;首页却正常 200。

定位:Redback 的 CSRF 校验同时看 Origin 头与请求主机是否匹配——用 127.0.0.1 访问但 Origin 写 localhost(或端口对不上)即被拒(实测复现)。

解决:Origin 与访问 URL 的主机端口保持一致;改用 http://localhost:8080 访问 + 同值 Origin 后,ping 正常返回 Yeah Baby It rocks!。改了 compose 对外端口(如 "18080:8080")时,Origin 同步写外部地址(如 http://localhost:18080)。

9.3 启动即退出或反复重启

排查顺序(命令均在宿主机执行):

docker compose ps                       # 看 STATUS 是否 Restarting
docker logs --tail 30 archiva-server    # wrapper console 输出
docker exec archiva-server tail -30 /opt/archiva/logs/archiva.log
docker inspect archiva-server --format '{{.State.OOMKilled}}'

常见根因:挂载目录属主不对(Archiva 以 root 运行,挂载目录 root 可写即可);mem_limit 低于实际需求(堆 256/512 + PermGen 128MB 稳态约 430MB,上限至少 768MB);8080 被宿主机其他进程占用(docker compose up 时直接报 bind failed,换端口映射)。

9.4 制品存储误挂成嵌套目录

现象:想把仓库直接落在宿主机某路径,挂载 ./repositories/internal:/opt/archiva/repositories/internal 后 Archiva 启动报错或目录混乱。

定位:首启要用 ./repositories/internal 相对基准创建内置仓库,把仓库子目录本身挂死会与该逻辑冲突(另见 4.4 的嵌套目录怪癖)。

解决:挂 ./repositories 父目录(本文方式),首启完成后再按需把自建仓库 location 指到挂载目录内的子路径(绝对路径)。

十、参考链接