Skip to content

Tengine-3.2.0-rc2

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Aug 16:06
· 21 commits to master since this release
793e88b

Chinese changelog: CHANGES.cn

This is the second release candidate of Tengine 3.2.0, the first release since 3.1.0 (October 2023). Relative to RC1 the server code is unchanged apart from one xquic fix — this candidate completes the release surface, so testing the packages and the container images is what helps most. Please do not use it in production yet.

What to test

We are especially interested in reports about the distribution packages and container images, HTTP/3 over xquic on lossy networks, and the load-balancing changes. Please open an issue with the output of tengine -V, the relevant configuration, and the platform.

New in RC2

  • All packages are signed. RPMs carry an in-band GPG signature, and both checksum files are signed detached. Key fingerprint: 8F5B 4D9F CA8E 2BFF 3E5E E958 25F0 7CF8 36E3 EC6A @lianglli
  • Debug symbols ship separately as -debuginfo / -debugsource (rpm), -dbgsym (deb) and -dbg (apk), with their own SHA256SUMS.debug @lianglli
  • ngx_http_perl_module is a separate subpackage (tengine-module-perl, tengine-mod-perl on Alpine), so the base install no longer pulls in libperl. Each container image also has a -perl variant with the module preloaded @lianglli
  • The package matrix now matches the platforms nginx publishes for: SLES 16, openEuler 22.03, Anolis 23 and Ubuntu 26.04 are covered, and Alpine ships for 3.21 through 3.24. The Alpine image moved to 3.24 @lianglli
  • Container image tags follow the nginx official scheme: minor and major series, floating aliases and base-suffixed variants — a pre-release only gets the version-pinned tags @lianglli
  • The default install layout for source builds is named after Tengine: prefix /usr/local/tengine, binary sbin/tengine, configuration conf/tengine.conf @lianglli
  • xquic: a session ticket key that cannot be read is now reported at warning level and closes the stream, instead of each worker silently falling back to a random key — which made 0-RTT always fail with more than one worker @lianglli

Security

Highlights

  • core updated to nginx 1.31.3 @lianglli
  • HTTP/3 connection management and multiplexing, for lower latency and higher resilience to packet loss on unstable networks, with BBR as the default congestion control [xquic] @lianglli @lurker-Chen
  • distribution packages (rpm, deb and apk) and multi-arch container images, all built with the full feature set — Tongsuo, xquic and Lua @lianglli
  • new module ngx_zstd for Zstandard response compression and serving pre-compressed static files @lianglli
  • new module ngx_http_upstream_iwrr_module, a weighted round-robin with O(1) time and O(n) memory @jizhuozhi
  • request and upstream timing statistics variables, e.g. $request_recv_time, $response_send_time, $server_rt and $upstream_first_pkg_time @lianglli
  • dynamically configure failover to a backup upstream or a redirect by response status code [tengine-ingress] @lianglli
  • ngx_http_lua_module updated to 0.10.29, which adds PCRE2 support @lianglli
  • ngx_http_upstream_rbtree_lookup() is now a public API, so third-party modules can look up an upstream by name @lhanjian

49 changes in total: 18 features, 17 bugfixes, 8 security fixes and 6 changes — the complete list is in CHANGES.te.

Which image tags to use

Use the version-pinned tags (3.2.0-rc2, 3.2.0-rc2-alpine, and their -perl variants). Tags matching *-dev-* are throwaway builds from manual CI runs used to verify the publishing path; they are unannounced and may be removed at any time. A pre-release does not move latest, alpine, 3.2 or 3, so a plain docker pull ghcr.io/alibaba/tengine still gives you 3.1.0.

Known limitations in RC2

  • ngx_http_tunnel_module is optional and off by default — it conflicts with ngx_http_proxy_connect_module on the CONNECT method.
  • least_time and sticky are disabled in the HTTP/2 rework and are being revisited.
  • The package file names carry no rc2 marker; artifacts here are named 3.2.0-<timestamp>. rpm's Version: and Alpine's pkgver do not allow -, and dpkg would rank 3.2.0-rc2 above the final 3.2.0.
  • Packages are built for x86_64 and aarch64 only.
  • GitHub rewrites ~ to . in release asset names, so the deb file names here differ from the ones recorded in SHA256SUMS (.bookworm versus ~bookworm). The contents are unaffected — see the Verify section for how to check a deb.

Every artifact here is built with the full feature set: Tongsuo (NTLS / TLCP, Chinese cryptography), xquic (QUIC and HTTP/3) and the LuaJIT scripting stack, all from the versions pinned in packages/build/deps.env. Tongsuo is linked statically, so these builds do not follow the system OpenSSL.

The server installs as /usr/sbin/tengine, configured through /etc/tengine/tengine.conf, and can coexist with a distro nginx.

Install

RPM (RHEL / Rocky / Alma / Anolis / openEuler / SLES) — replace el9 with your platform's tag (el7, el8, el10, an8, an23, oe2203, oe2403, sles15, sles16):

rpm --import https://github.com/alibaba/tengine/releases/download/3.2.0-rc2/tengine-packaging-key.asc
dnf install https://github.com/alibaba/tengine/releases/download/3.2.0-rc2/tengine-3.2.0-20260807154919.el9.x86_64.rpm

DEB (Debian / Ubuntu) — replace bookworm with your codename (bullseye, trixie, jammy, noble, resolute):

curl -fLO https://github.com/alibaba/tengine/releases/download/3.2.0-rc2/tengine_3.2.0-20260807154919.bookworm_amd64.deb
apt install ./tengine_3.2.0-20260807154919.bookworm_amd64.deb

Alpine — replace alpine324 with your release (alpine321, alpine322, alpine323):

curl -fLo /etc/apk/keys/tengine-packaging.rsa.pub \
    https://github.com/alibaba/tengine/releases/download/3.2.0-rc2/tengine-packaging.rsa.pub
curl -fLO https://github.com/alibaba/tengine/releases/download/3.2.0-rc2/tengine-3.2.0_p20260807154919-r0.alpine324.x86_64.apk
apk add ./tengine-3.2.0_p20260807154919-r0.alpine324.x86_64.apk

Dropping the public key first is what lets apk add work without --allow-untrusted.

Container images

docker pull ghcr.io/alibaba/tengine:3.2.0-rc2
docker pull ghcr.io/alibaba/tengine:3.2.0-rc2-alpine

Both are multi-arch (amd64 + arm64). A -perl variant of each adds ngx_http_perl_module (3.2.0-rc2-perl, 3.2.0-rc2-alpine-perl); the module is already loaded in the shipped configuration, so perl, perl_set and perl_modules work out of the box.

Perl module

In the packages, ngx_http_perl_module is a separate subpackage (tengine-module-perl, tengine-mod-perl on Alpine) so the base install does not pull in libperl. It is dynamic and not loaded by default; add

load_module /usr/lib/tengine/modules/ngx_http_perl_module.so;

to the main context (/usr/lib64 on the RHEL family).

Debug symbols

The -debuginfo / -debugsource (rpm), -dbgsym (deb) and -dbg (apk) packages are listed alongside the runtime packages and are only needed to read a core dump or attach a debugger. They have their own checksum file, SHA256SUMS.debug.

Verify

Checksums — --ignore-missing restricts the check to the files you actually downloaded:

curl -fLO https://github.com/alibaba/tengine/releases/download/3.2.0-rc2/SHA256SUMS
sha256sum --ignore-missing -c SHA256SUMS

On Alpine the busybox sha256sum has no such flag — use grep <filename> SHA256SUMS | sha256sum -c there, or install coreutils.

For a deb, rename it back before checking: GitHub rewrites ~ to . in asset names, while SHA256SUMS records the name the package was built with.

f=tengine_3.2.0-20260807154919.bookworm_amd64.deb
mv "$f" "${f/.bookworm/~bookworm}"
grep -F "${f/.bookworm/~bookworm}" SHA256SUMS | sha256sum -c

The checksum file itself is signed, which is what covers the deb packages — they carry no in-band signature, since Debian's trust model signs a repository rather than individual files:

curl -fLO https://github.com/alibaba/tengine/releases/download/3.2.0-rc2/SHA256SUMS.asc
curl -fLO https://github.com/alibaba/tengine/releases/download/3.2.0-rc2/tengine-packaging-key.asc
gpg --import tengine-packaging-key.asc
gpg --verify SHA256SUMS.asc SHA256SUMS

The imported key must show the fingerprint 8F5B4D9FCA8E2BFF3E5EE95825F07CF836E3EC6A.

The rpm packages are signed in-band with the same key, so once it is imported into rpm they verify individually:

rpm --import https://github.com/alibaba/tengine/releases/download/3.2.0-rc2/tengine-packaging-key.asc
rpm --checksig tengine-3.2.0-20260807154919.el9.x86_64.rpm

What's Changed

  • Credit a missing contribution and fix the release notes install snippets by @lianglli in #2068
  • Build: align the package matrix with the platforms nginx supports by @lianglli in #2069
  • Build: name the default install layout after Tengine by @lianglli in #2070
  • Build: fix sles16 image tag and pin xquic CMake generator by @lianglli in #2071
  • Build: retry the container image pull before building a target by @lianglli in #2072
  • Docker: align the image base and tag scheme with the nginx official images by @lianglli in #2073
  • Packaging: extend the distro matrix and publish -perl container images by @lianglli in #2075
  • Packaging: extend the distro matrix, publish -perl images, refresh the CI actions by @lianglli in #2076
  • Packaging: fix two missing build artifacts in the -perl images and Ubuntu debs by @lianglli in #2077
  • Packaging: sign the release artifacts, split out debug symbols, and refresh the docs and default pages by @lianglli in #2078
  • Build: install the perl development headers in the container bootstrap by @lianglli in #2079
  • Build: keep the apk package index so abuild can resolve makedepends by @lianglli in #2081
  • CI: verify the apk packages and stop exempting the el7 aarch64 build by @lianglli in #2082
  • Alpine: drop g++ from makedepends, build-base already carries it by @lianglli in #2083
  • XQUIC: warn on session ticket key failure and close the stream by @lianglli in #2084

Full Changelog: 3.2.0-rc1...3.2.0-rc2