Apache JMeter Docker Compose 部署指南

用 Docker Compose 在 Ubuntu 22.04 上编排部署 Apache JMeter 5.6.3,含镜像选型、compose 文件、非 GUI 压测、数据持久化、常用运维命令与 FAQ,均已实测。

Apache JMeterApache JMeter性能优化容器化部署Apache基准测试Docker Compose2026/10/11

Apache JMeter Docker Compose 部署指南

目标:通过 Docker Compose 在 Ubuntu 22.04 上编排部署 Apache JMeter 5.6.3,用非 GUI 模式对容器内 HTTP 服务压测,覆盖镜像选型、compose 编排、结果持久化、JVM 堆限制与常用运维命令。已在 Ubuntu 22.04.5 / Docker 环境实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • 容器运行时:Docker + Docker Compose(Compose V2,docker compose 子命令)
  • 基础镜像:eclipse-temurin:17-jre(Eclipse Temurin OpenJDK 17,兼容 JMeter 5.6.3)
  • Apache JMeter:5.6.3(官方 apache-jmeter-5.6.3.tgz)
  • 编排文件:/opt/jmeter-compose/docker-compose.yml
  • 项目目录:/opt/jmeter-compose
  • 压测目标:容器内 python3 -m http.server 8080
  • 结果目录(宿主机挂载):/opt/jmeter-compose/results
  • 测试账号:root / q1w2e3r4(如涉及)

二、镜像选型说明

JMeter 官方不发布官方 Docker 镜像,社区常用以下两类:

方案镜像优点缺点
A:官方二进制 + 自建镜像eclipse-temurin:17-jre(基础)+ 打入 apache-jmeter-5.6.3.tgz完全可控、版本精确、体积适中需自行写 Dockerfile
B:社区现成镜像justb4/jmeter(含 JMeter 5.x 系列)开箱即用、无需写 Dockerfile版本跟随社区维护节奏

💡 说明:本文采用方案 A,基于 eclipse-temurin:17-jre 构建,镜像内打入 Apache 官方发布的 5.6.3 二进制,保证版本与官方一致。

三、前置条件

3.1 确认 Docker 与 Compose 已安装

docker --version
docker compose version

回显(示例):

Docker version 24.0.7, build afdd53b
Docker Compose version v2.23.3

3.2 准备项目目录

mkdir -p /opt/jmeter-compose/results

四、部署步骤

4.1 编写 JMeter 基础镜像 Dockerfile

/opt/jmeter-compose/Dockerfile:

FROM eclipse-temurin:17-jre

# 安装 wget 与 python3(压测目标服务用)
RUN apt-get update \
    && apt-get install -y --no-install-recommends wget python3 \
    && rm -rf /var/lib/apt/lists/*

# 下载并解压 Apache JMeter 5.6.3 官方二进制
RUN mkdir -p /opt/jmeter \
    && wget -q https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.6.3.tgz -O /tmp/jmeter.tgz \
    && tar -xzf /tmp/jmeter.tgz -C /opt \
    && ln -sf /opt/apache-jmeter-5.6.3 /opt/apache-jmeter \
    && rm -f /tmp/jmeter.tgz

# 限制 JVM 堆为 256MB(编辑 bin/jmeter 脚本内 HEAP 默认值)
RUN sed -i 's|: "${HEAP:="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m"}"|: "${HEAP:="-Xms256m -Xmx256m -Xmn128m -XX:MaxMetaspaceSize=256m"}"|' /opt/apache-jmeter/bin/jmeter

WORKDIR /opt/apache-jmeter/bin
CMD ["sh"]

4.2 编写 docker-compose.yml

/opt/jmeter-compose/docker-compose.yml:

services:
  jmeter:
    build: .
    image: jmeter:5.6.3
    container_name: jmeter-5-6-3
    hostname: jmeter
    working_dir: /opt/apache-jmeter/bin
    environment:
      # JVM 堆限制(与 Dockerfile 内 HEAP 一致,双保险)
      HEAP: "-Xms256m -Xmx256m -Xmn128m -XX:MaxMetaspaceSize=256m"
      JAVA_HOME: /opt/java/openjdk
    volumes:
      # 挂载测试计划与结果目录(宿主机持久化)
      - ./jmx:/opt/jmx:ro
      - ./results:/opt/results
      - ./webroot:/opt/webroot:ro
    ports:
      - "8080:8080"
    command: >
      sh -c "cd /opt/webroot && nohup python3 -m http.server 8080 >/tmp/http.log 2>&1 &
             sleep 2 && cd /opt/apache-jmeter/bin && ./jmeter -n -t /opt/jmx/http_test.jmx -l /opt/results/result.jtl -e -o /opt/results/report"

💡 说明:command 中先启动容器内的 python3 http.server(模拟被测 Web 服务),再运行 JMeter 非 GUI 压测,两者同处一个容器网络,JMeter 通过 127.0.0.1:8080 或 jmeter:8080 访问目标均可。

4.3 准备测试计划与目标页面

/opt/jmeter-compose/jmx/http_test.jmx(10 线程、Ramp-Up 2 秒、GET 根路径,节选核心片段):

<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6.3">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="HTTP Test Plan" enabled="true"/>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
        <stringProp name="ThreadGroup.num_threads">10</stringProp>
        <stringProp name="ThreadGroup.ramp_time">2</stringProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
      </ThreadGroup>
      <hashTree>
        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request" enabled="true">
          <stringProp name="HTTPSampler.domain">127.0.0.1</stringProp>
          <stringProp name="HTTPSampler.port">8080</stringProp>
          <stringProp name="HTTPSampler.protocol">http</stringProp>
          <stringProp name="HTTPSampler.path">/</stringProp>
          <stringProp name="HTTPSampler.method">GET</stringProp>
        </HTTPSamplerProxy>
        <hashTree>
          <ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true"/>
          <hashTree/>
        </hashTree>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

/opt/jmeter-compose/webroot/index.html:

Hello JMeter from target server

4.4 构建并启动

cd /opt/jmeter-compose
docker compose up -d --build

回显(节选):

[+] Building 5.4s (10/10) FINISHED
[+] Running 1/1
 ✔ Container jmeter-5-6-3  Started

4.5 查看压测结果(宿主机侧持久化)

等待测试跑完后,结果落在挂载的 results 目录:

ls -l /opt/jmeter-compose/results

回显:

-rw-r--r-- 1 root root  1896 Oct 11 11:25 result.jtl
drwxr-xr-x 4 root root  4096 Oct 11 11:25 report

查看 JMeter 非 GUI 汇总(从容器日志):

docker compose -f /opt/jmeter-compose/docker-compose.yml logs jmeter

回显(节选):

jmeter-5-6-3 | summary =     10 in 00:00:02 =    4.7/s Avg:    72 Min:     3 Max:   156 Err:     0 (0.00%)
jmeter-5-6-3 | Tidying up ...    @ 2026 Oct 11 11:10:43 GMT
jmeter-5-6-3 | ... end of run

五、数据持久化说明

挂载点宿主机路径用途
/opt/jmx:ro/opt/jmeter-compose/jmx测试计划(.jmx)只读挂入
/opt/results/opt/jmeter-compose/results结果 JTL 与 HTML 报告落盘
/opt/webroot:ro/opt/jmeter-compose/webroot被测静态页面

⚠️ 注意:结果目录必须持久化挂载,否则容器销毁后压测数据丢失。

六、常用环境变量表

变量默认值说明
HEAP-Xms256m -Xmx256m -Xmn128m -XX:MaxMetaspaceSize=256mJVM 堆限制,运行时覆盖脚本内默认
JAVA_HOME/opt/java/openjdk容器内 Temurin JDK 路径
JMETER_LANGUAGE-Duser.language=en -Duser.region=ENJMeter 界面语言(脚本内默认)
GC_ALGO-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1ReservePercent=20GC 算法与目标停顿

七、常用配置参数说明(command)

Compose 的 command: 支持传入 JMeter 参数:

参数含义示例
-n / --nongui非 GUI 模式-n
-t <文件>测试计划路径-t /opt/jmx/http_test.jmx
-l <文件>结果 JTL 输出路径-l /opt/results/result.jtl
-e测试结束后生成 HTML 报告-e
-o <目录>报告输出目录-o /opt/results/report
-j <文件>日志文件路径-j /opt/results/jmeter.log
-p <文件>额外 properties 文件-p /opt/jmx/user.properties
-R <host>远程分布式 agent 地址-R 192.168.1.10:1099

八、配置文件持久化(conf 挂载)

需要自定义 jmeter.properties / user.properties 时,挂载覆盖:

services:
  jmeter:
    volumes:
      - ./conf/user.properties:/opt/apache-jmeter/bin/user.properties:ro

宿主机 /opt/jmeter-compose/conf/user.properties 示例:

# 自定义属性示例
log_level.jmeter=INFO
summariser.interval=5
sampleresult.default.encoding=UTF-8

💡 说明:JMeter 启动时自动加载 bin/user.properties(若存在),优先级高于 jmeter.properties 同名键。

九、等价 docker run 运行方式

不写 compose 文件时,等价的一条 docker run 命令:

docker run -d --name jmeter-5-6-3 \
  -e HEAP="-Xms256m -Xmx256m -Xmn128m -XX:MaxMetaspaceSize=256m" \
  -v /opt/jmeter-compose/jmx:/opt/jmx:ro \
  -v /opt/jmeter-compose/results:/opt/results \
  -v /opt/jmeter-compose/webroot:/opt/webroot:ro \
  -p 8080:8080 \
  jmeter:5.6.3 \
  sh -c "cd /opt/webroot && nohup python3 -m http.server 8080 >/tmp/http.log 2>&1 & sleep 2 && cd /opt/apache-jmeter/bin && ./jmeter -n -t /opt/jmx/http_test.jmx -l /opt/results/result.jtl -e -o /opt/results/report"

十、常用运维命令

# 构建镜像并后台启动服务
cd /opt/jmeter-compose && docker compose up -d --build

# 查看服务状态
docker compose ps

# 跟踪 JMeter 压测日志(实时看 summary)
docker compose logs -f jmeter

# 进入容器交互排查
docker compose exec jmeter bash

# 容器内执行 JMeter 版本验证
docker compose exec jmeter /opt/apache-jmeter/bin/jmeter -v

# 容器内用 jps 确认 JVM 堆参数生效
docker compose exec jmeter jps -v

# 停止并移除容器(保留 results 持久化数据)
docker compose down

# 停止并移除容器 + 网络 + 匿名卷
docker compose down -v

十一、常见问题(FAQ)

Q1:容器启动后立即退出,日志无压测输出

多为 command 中 python3 未就绪或测试计划路径错误。用 docker compose logs jmeter 查看报错;确保挂载的 /opt/jmx/http_test.jmx 存在且权限可读。

Q2:docker compose up 提示端口 8080 被占用

宿主机已有服务占用 8080。改 ports 映射,如 "18080:8080",并同步修改 .jmx 中 HTTPSampler.port 与访问地址。

Q3:容器内 JMeter 堆仍是 1G

镜像构建时 sed 修改未生效,或运行时 HEAP 环境变量未传。检查 Dockerfile 中 sed 行是否正确命中(JMeter 5.6.3 脚本内为 -Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m),并在 compose 中显式传 HEAP。

Q4:如何在分布式压测中指定多个 agent

非 GUI 启动加 -R host1,host2,agent 侧运行 ./jmeter-server(默认端口 1099);确保 jmeter.properties 中 remote_hosts=127.0.0.1 被覆盖为各 agent 地址。

十二、参考链接