Apache Traffic Server 10.2.0 Docker Compose 部署指南

本文讲解以 Docker Compose 部署 Traffic Server 10.2.0:官方镜像与自建 Dockerfile 路线选型、编排样例、缓存卷与配置持久化、等价 docker run 与运维命令,流程经真实部署验证。

Apache Traffic ServerApache Traffic Server2026/10/12

Apache Traffic Server 10.2.0 Docker Compose 部署指南

一、环境信息

项目内容
组件版本Apache Traffic Server 10.2.0
宿主系统Linux x86_64(实测 Ubuntu 22.04 基座)
Docker 版本29.8.0(实测版本,24 及以上均可)
Compose 版本v5.5.1(实测版本,v2.x 起语法兼容)
服务端口容器内 8080(HTTP 代理)
配置目录/usr/local/etc/trafficserver(自建镜像)
缓存目录/usr/local/var/trafficserver(自建镜像)

二、镜像选型说明

2.1 两条路线对比

对比项官方镜像 apache/trafficserver自建镜像(本文实测主线)
获取方式Docker Hub 拉取Dockerfile 从官方源码构建
版本10.2.0 等官方 tag任意官方发行版本
安装前缀/usr/local/usr/local(与本文一致)
网络依赖需要 Docker Hub 可达仅需 downloads.apache.org 可达
定制性无法改编译参数可加插件、关闭测试目标、选 OpenSSL 版本

实测提示:部分受限网络环境下 Docker Hub 的 apache/trafficserver 命名空间拉取会被 registry 代理拒绝(实测 docker pull apache/trafficserver:10.2.0 返回 denied),此时自建镜像是唯一可行路线;本文全部编排与命令以自建镜像实测通过为准,官方镜像用法在其可直接拉取的环境下等价适用。

2.2 自建 Dockerfile(实测通过版本,产物 703MB)

FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential cmake libssl-dev libpcre2-dev libcap-dev libhwloc-dev \
    libcurl4-openssl-dev tcl-dev zlib1g-dev bison flex libbrotli-dev liblzma-dev \
    libluajit-5.1-dev pkg-config \
    curl ca-certificates && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /usr/local/src \
    && curl -fL https://downloads.apache.org/trafficserver/trafficserver-10.2.0.tar.bz2 -o /tmp/ats.tar.bz2 \
    && tar xjf /tmp/ats.tar.bz2 -C /usr/local/src \
    && cd /usr/local/src/trafficserver-10.2.0 \
    && cmake -B build -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DBUILD_REGRESSION_TESTING=OFF \
    && cmake --build build -j"$(nproc)" && cmake --install build \
    && rm -rf /usr/local/src /tmp/ats.tar.bz2
RUN useradd -r -s /usr/sbin/nologin ats \
    && mkdir -p /usr/local/var/trafficserver /usr/local/var/log/trafficserver \
    && chown -R ats:ats /usr/local/var
USER ats
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/traffic_server"]

构建要点(均为实测踩坑结论):

  1. pkg-config 与 libpcre2-dev 是 CMake 配置必需项,缺 pkg-config 报 Could NOT find PkgConfig,缺 PCRE2 报 No package 'libpcre2-8'。
  2. libluajit-5.1-dev 缺失时 CMake 的 luajit 自动探测直接报错终止,必须安装。
  3. BUILD_REGRESSION_TESTING=OFF 跳过单元测试编译,12 核实测构建时间从约 20 分钟降到 10 分钟左右,镜像体积从 2.1GB 级降到 703MB。
  4. 运行用户 ats 通过 USER 指令固定,非 root 启动时 ATS 日志确认 Traffic Server is running unprivileged。

构建镜像:

docker build -t ats-selfbuilt:10.2.0 .

三、前置条件

  1. 宿主机已安装 Docker 与 Compose 插件:
docker version --format '{{.Server.Version}}'
docker compose version
Docker Compose version v5.5.1
  1. 镜像就绪:官方环境直接 docker pull apache/trafficserver:10.2.0;受限环境先完成上节自建构建。

  2. 宿主机 8080 端口空闲:

ss -lnt | grep 8080 || echo '端口空闲'
  1. 创建部署目录与配置文件:
mkdir -p /opt/ats-compose/conf && cd /opt/ats-compose

四、部署步骤

4.1 准备配置文件

写反向代理映射(conf/remap.config):

printf 'map / http://example.com/\n' > conf/remap.config

写缓存存储(conf/storage.config,路径指向容器内挂载的命名卷):

printf '/usr/local/var/trafficserver 256M\n' > conf/storage.config

4.2 编写 docker-compose.yml

services:
  trafficserver:
    image: ats-selfbuilt:10.2.0
    container_name: trafficserver
    ports:
      - "8080:8080"
    volumes:
      - ./conf/remap.config:/usr/local/etc/trafficserver/remap.config:ro
      - ./conf/storage.config:/usr/local/etc/trafficserver/storage.config:ro
      - cache-data:/usr/local/var/trafficserver
    ulimits:
      nofile:
        soft: 131072
        hard: 131072
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "/usr/local/bin/traffic_ctl", "server", "status"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 20s
volumes:
  cache-data:

设计说明:

  1. 配置文件以只读方式挂载,容器内以 ats 用户运行无法也无需改写配置,变更走宿主机改文件加重启。
  2. cache-data 命名卷承载缓存文件,容器重建不丢缓存。
  3. healthcheck 用容器内 traffic_ctl 探测 JSONRPC,比 TCP 探测更能反映服务真实可用性。
  4. nofile 131072 匹配高并发连接需求。

4.3 启动服务

cd /opt/ats-compose && docker compose up -d
 Container trafficserver Started

查看状态(实测启动约 10 秒后转为 healthy):

docker compose ps
NAME            IMAGE                   STATUS
trafficserver   ats-selfbuilt:10.2.0    Up 12 seconds (healthy)

4.4 启动验证

请求验证代理链路(宿主机或容器内均可):

curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1:8080/
HTTP 200

第二次请求确认缓存生效:

curl -sI http://127.0.0.1:8080/ | grep -E '^Age|^Server'
Age: 2
Server: ATS/10.2.0

容器内确认缓存文件与指标:

docker exec trafficserver ls -lh /usr/local/var/trafficserver/cache.db
-rw-r--r-- 1 ats ats 256M Oct 12 07:11 /usr/local/var/trafficserver/cache.db
docker exec trafficserver /usr/local/bin/traffic_ctl metric get proxy.process.http.incoming_requests
proxy.process.http.incoming_requests 1

查看启动日志:

docker compose logs --tail 5 trafficserver
trafficserver  | [Oct 12 07:10:10.804] traffic_server NOTE: records parsing completed.
trafficserver  | [Oct 12 07:10:10.804] traffic_server NOTE: /usr/local/etc/trafficserver/records.yaml finished loading
trafficserver  | [Oct 12 07:10:10.805] traffic_server NOTE: Traffic Server is running unprivileged, not switching to user 'nobody'

五、数据持久化说明

数据容器内路径持久化方式说明
缓存/usr/local/var/trafficserver命名卷 cache-datacache.db 落卷,容器删除重建不丢;compose down 不删卷
remap 规则/usr/local/etc/trafficserver/remap.configbind 挂载(只读)宿主机单文件维护
存储定义/usr/local/etc/trafficserver/storage.configbind 挂载(只读)路径必须指向卷内挂载点
运行时锁与 socket/usr/local/var/trafficserver随缓存卷server.lock 与 jsonrpc20.sock 落在卷内
日志/usr/local/var/log/trafficserver可选 bind 挂载默认随容器,采集接入时挂出到宿主机

实测结论:docker compose down 后命名卷 cache-data 依然保留(docker volume ls 可见 ats-compose_cache-data),缓存命中数据跨生命周期存活;要彻底重建缓存执行 docker compose down -v。

六、常用环境变量表

容器内 ATS 相关环境变量:

变量示例值作用
TS_RUNROOT/usr/local指定 traffic_server 运行根(runroot 沙箱),多实例隔离时设置;单实例默认免设

Compose 层变量(写入 .env 文件供 docker-compose.yml 引用):

变量示例值用途
ATS_IMAGEats-selfbuilt:10.2.0镜像与版本
ATS_HTTP_PORT8080宿主机对外端口
ATS_CACHE_SIZE256M缓存大小,渲染进 storage.config
ATS_CACHE_VOLcache-data缓存命名卷名

使用 .env 后 docker-compose.yml 的 image 写为 ${ATS_IMAGE},ports 写为 "${ATS_HTTP_PORT}:8080"。生成 .env:

printf 'ATS_IMAGE=ats-selfbuilt:10.2.0\nATS_HTTP_PORT=8080\n' > .env

说明:官方与自建镜像均无强制的启动环境变量,配置全部经文件挂载;TS_RUNROOT 仅在单容器多进程或特殊路径需求时使用。

七、常用配置参数说明

容器内主配置为 /usr/local/etc/trafficserver/records.yaml(YAML 格式)。部署中最常调整的参数:

参数(点分名)YAML 片段默认值容器场景建议
proxy.config.http.server_portshttp.server_ports8080 8080:ipv6容器内保持 8080,由端口映射控制对外端口
proxy.config.http.insert_response_via_strhttp.insert_response_via_str0调试期设 1 便于观察命中
proxy.config.url_remap.remap_requiredurl_remap.remap_required1反向代理保持 1
proxy.config.cache.ram_cache.sizecache.ram_cache.size-1按容器内存限制设定,避免 OOM
proxy.config.net.connections_throttlenet.connections_throttle30000与 nofile 与宿主负载匹配

因 records.yaml 未被挂载时可进入容器查看默认值:

docker exec trafficserver cat /usr/local/etc/trafficserver/records.yaml | head -20

需要整体定制时把 records.yaml 也加入只读挂载列表,宿主机维护一份完整配置。修改挂载的配置后重启容器生效:

docker compose restart trafficserver

storage.config 变更(缓存扩容)同样重启生效,路径必须落在挂载卷内,实测改为 512M 后 cache.db 重新初始化为 536870912 字节。

八、配置文件持久化

推荐目录结构(宿主机):

/opt/ats-compose/
├── docker-compose.yml
├── .env
└── conf/
    ├── records.yaml
    ├── remap.config
    └── storage.config

对应卷声明(在第四节基础上追加 records.yaml):

    volumes:
      - ./conf/records.yaml:/usr/local/etc/trafficserver/records.yaml:ro
      - ./conf/remap.config:/usr/local/etc/trafficserver/remap.config:ro
      - ./conf/storage.config:/usr/local/etc/trafficserver/storage.config:ro
      - cache-data:/usr/local/var/trafficserver

持久化校验方法:修改宿主机 conf/remap.config 后重启,确认新规则生效:

docker compose restart trafficserver
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/

配置文件模板从镜像导出(首次部署前取默认副本到宿主机):

docker run --rm --entrypoint cat ats-selfbuilt:10.2.0 /usr/local/etc/trafficserver/records.yaml > conf/records.yaml

九、等价 docker run 运行方式

不使用 Compose 时,以下命令与上文编排等价:

docker run -d --name trafficserver \
  -p 8080:8080 \
  --ulimit nofile=131072:131072 \
  --restart unless-stopped \
  -v /opt/ats-compose/conf/remap.config:/usr/local/etc/trafficserver/remap.config:ro \
  -v /opt/ats-compose/conf/storage.config:/usr/local/etc/trafficserver/storage.config:ro \
  -v ats-cache:/usr/local/var/trafficserver \
  ats-selfbuilt:10.2.0

清理等价命令:

docker rm -f trafficserver
docker volume rm ats-cache

使用官方镜像环境下的等价运行方式(镜像可直接拉取时):

docker run -d --name trafficserver \
  -p 8080:8080 \
  --ulimit nofile=131072:131072 \
  apache/trafficserver:10.2.0

官方镜像的配置路径同为 /usr/local 前缀,挂载方式一致;如使用其他第三方镜像,先确认其 ENTRYPOINT 与配置前缀再挂载。

十、常用运维命令

状态与日志:

docker compose ps
docker compose logs -f --tail 100 trafficserver
docker stats trafficserver --no-stream

进入容器运维(traffic_ctl 全套可用):

docker exec -it trafficserver /usr/local/bin/traffic_ctl server status
docker exec -it trafficserver /usr/local/bin/traffic_ctl config diff
docker exec -it trafficserver /usr/local/bin/traffic_ctl metric get proxy.process.http.incoming_requests

在线重载配置(宿主机改完挂载文件后):

docker exec trafficserver /usr/local/bin/traffic_ctl config reload

重启与停止:

docker compose restart trafficserver
docker compose down

彻底重建(含缓存数据,谨慎):

docker compose down -v

镜像与容器信息查看:

docker inspect trafficserver --format '{{.State.Health.Status}}'
healthy

十一、常见问题

Q1:容器反复重启,日志报 lockfile Permission denied?

以 root 启动时 ATS 自动切换 nobody,而镜像内运行目录属主不匹配导致锁文件无法创建。自建镜像已用 USER ats 规避;若镜像以 root 启动,把 entrypoint 改为自愈写法(实测通过):

    entrypoint: ["/bin/sh", "-c", "mkdir -p /usr/local/var/trafficserver /usr/local/var/log/trafficserver && chown -R 65534:65534 /usr/local/var/trafficserver /usr/local/var/log/trafficserver && rm -f /usr/local/var/trafficserver/server.lock /usr/local/var/trafficserver/jsonrpc20.sock && exec /usr/local/bin/traffic_server"]

Q2:healthcheck 一直 unhealthy,traffic_ctl 报 RPC Node Error?

进程异常退出后 jsonrpc20.sock 残留,healthcheck 的 traffic_ctl 连不上。按 Q1 的 entrypoint 自愈写法在启动前清理 socket 文件,或手动清理后重启:

docker exec trafficserver sh -c 'rm -f /usr/local/var/trafficserver/jsonrpc20.sock /usr/local/var/trafficserver/jsonrpc20.lock'
docker compose restart trafficserver

Q3:docker pull apache/trafficserver 报 denied?

受 registry 代理或镜像仓库访问策略限制(实测部分网络环境该命名空间整体 denied)。改走本文第二节的自建 Dockerfile 路线,产物功能等价。

Q4:启动报 Address already in use 但容器内没有进程?

宿主机端口被其他进程占用,或上一个容器处于优雅排空未完全退出。确认宿主机 8080 占用并更换映射端口:

ss -lntp | grep 8080
docker rm -f trafficserver
docker compose up -d

Q5:容器内没有 curl 怎么验证服务?

镜像为瘦身未装 curl 时用 wget 或宿主机请求映射端口:

docker exec trafficserver wget -qO- -T 10 http://127.0.0.1:8080/ | head -c 80

Q6:用 docker commit 生成的镜像 compose 起不来或跑起的是 systemd?

commit 自带原容器配置,若源容器 CMD 是 /sbin/init,则新镜像默认仍执行 init 而非 traffic_server。在 compose 中显式覆盖:

    entrypoint: ["/usr/local/bin/traffic_server"]

十二、参考链接

  1. Docker Compose 官方文档:https://docs.docker.com/compose/
  2. Apache Traffic Server 官方镜像页:https://hub.docker.com/r/apache/trafficserver
  3. ATS 官方 Docker 构建资料(源码 contrib 目录):https://github.com/apache/trafficserver
  4. records.yaml 参数参考:https://docs.trafficserver.apache.org/en/latest/admin-guide/files/records.yaml.en.html
  5. storage.config 参考:https://docs.trafficserver.apache.org/en/latest/admin-guide/files/storage.config.en.html
  6. ATS 运行与监控文档:https://docs.trafficserver.apache.org/en/latest/admin-guide/monitoring/traffic_ctl.en.html