Skip to content

Commit 7bdda3e

Browse files
authored
Zlib Alternatives for Nginx
Since the Cloudflare Zlib fork has been deprecated, we implemented two experimental alternatives for Nginx: Zlib-ng and Zlib-rs. Both alternatives are designed to be drop-in replacements for the original Zlib, potentially providing improved performance and security. Both should be considered experimental, although they should be stable and performant. We encourage users to test both alternatives and provide feedback on their performance and compatibility with Nginx.
1 parent 2744251 commit 7bdda3e

8 files changed

Lines changed: 200 additions & 31 deletions

File tree

.github/ci-config/enginescript-variables-ci.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ PHP_VER="8.5"
1818
PHPMYADMIN_VER="5.2.3"
1919
PNGOUT_VER="20200115"
2020
ZLIB_VER="1.3.2"
21+
ZLIB_NG_VER="2.3.3"
22+
ZLIB_RS_VER="v0.6.0"
2123

2224
# EngineScript Plugins
2325
SSE_PLUGIN_VER="1.9.1"

.github/copilot-instructions.md

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,20 @@
22
applyTo: '**'
33
---
44

5-
# CRITICAL BEHAVIORS (Must Follow)
5+
# BEHAVIOR RULES
66

77
## Complete Code Analysis - No Shortcuts
88

9-
- Read files completely and thoroughly, minimum 1500 lines per read operation
10-
- Process entire files: all functions, classes, variables, imports, exports, structures
11-
- Reference specific sections throughout entire codebase to demonstrate full understanding
9+
- Read files completely and thoroughly before making changes
1210
- Understand complete context: how functions interact, variables used across entire file
1311

14-
## Direct Action - No Permission Asking
12+
## Communication Standards
1513

16-
- Do not ask for confirmation before making changes - proceed automatically
17-
- Only ask for confirmation when action could affect system stability or security
18-
- Change summaries should be concise, focusing on specific changes made
19-
- Never create change summaries as new .md files
20-
21-
## Clear Communication Standards
22-
23-
- Provide clear, concise, actionable information in chat interface only
14+
- Provide clear, concise, actionable information
2415
- Use formatting and styling to enhance readability
25-
- Avoid unnecessary verbosity or complexity in explanations
16+
- Change summaries should be concise, focusing on specific changes made
2617

27-
# PROJECT CONTEXT & FOCUS
18+
# PROJECT STANDARDS
2819

2920
## EngineScript - LEMP Server Automation
3021

@@ -44,13 +35,10 @@ applyTo: '**'
4435

4536
## System Compatibility & Standards
4637

47-
- **Target OS**: Ubuntu 24.04 LTS exclusively
4838
- **Architecture**: Follow Linux Filesystem Hierarchy Standard (FHS)
4939
- **Service Management**: systemd for all service configuration
5040
- **Security**: Production-ready configurations, secure by default, principle of least privilege
5141

52-
# ESSENTIAL STANDARDS
53-
5442
## Security & Data Handling (Critical)
5543

5644
- **Input Validation**: Sanitize all input/output, especially user-provided configuration data
@@ -61,7 +49,6 @@ applyTo: '**'
6149

6250
- **CHANGELOG.md**: Always document changes when modifying codebase (continuous improvement model)
6351
- **Key Files**: Keep updated: README.md, script headers, configuration templates
64-
- **Commit Messages**: Clear, descriptive messages explaining purpose and scope
6552
- **Breaking Changes**: Document new dependencies, system requirements prominently
6653
- **Manual Steps**: Document any required manual steps after updates
6754

@@ -73,8 +60,5 @@ applyTo: '**'
7360
- **Clean Code**: Remove unused code automatically, consistent patterns
7461
- **Separation**: Use configuration files and templates appropriately
7562
- **Backward Compatibility**: Maintain unless explicitly breaking changes required
76-
77-
## Performance & Reliability
78-
7963
- **Logging**: Actionable errors with appropriate detail levels
8064
- **Dependencies**: Verify compatibility when introducing new software

.github/workflows/software-version-check.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,34 @@ jobs:
212212
echo "::warning::Failed to fetch Zlib version, keeping current version"
213213
fi
214214
215+
# zlib-ng
216+
echo "::debug::Fetching zlib-ng version..."
217+
ZLIB_NG_API_RESPONSE=$(curl -s https://api.github.com/repos/zlib-ng/zlib-ng/releases/latest)
218+
echo "::debug::zlib-ng API Response: $ZLIB_NG_API_RESPONSE"
219+
220+
LATEST_ZLIB_NG=$(echo "$ZLIB_NG_API_RESPONSE" | jq -r '.tag_name // empty')
221+
echo "::debug::Parsed zlib-ng version: '$LATEST_ZLIB_NG'"
222+
223+
if [[ -n "$LATEST_ZLIB_NG" && "$LATEST_ZLIB_NG" != "null" ]]; then
224+
check_version "ZLIB_NG_VER" "$LATEST_ZLIB_NG"
225+
else
226+
echo "::warning::Failed to fetch zlib-ng version, keeping current version"
227+
fi
228+
229+
# zlib-rs
230+
echo "::debug::Fetching zlib-rs version..."
231+
ZLIB_RS_API_RESPONSE=$(curl -s https://api.github.com/repos/trifectatechfoundation/zlib-rs/releases/latest)
232+
echo "::debug::zlib-rs API Response: $ZLIB_RS_API_RESPONSE"
233+
234+
LATEST_ZLIB_RS=$(echo "$ZLIB_RS_API_RESPONSE" | jq -r '.tag_name // empty')
235+
echo "::debug::Parsed zlib-rs version: '$LATEST_ZLIB_RS'"
236+
237+
if [[ -n "$LATEST_ZLIB_RS" && "$LATEST_ZLIB_RS" != "null" ]]; then
238+
check_version "ZLIB_RS_VER" "$LATEST_ZLIB_RS"
239+
else
240+
echo "::warning::Failed to fetch zlib-rs version, keeping current version"
241+
fi
242+
215243
# liburing
216244
echo "::debug::Fetching liburing version..."
217245
LIBURING_API_RESPONSE=$(curl -s https://api.github.com/repos/axboe/liburing/tags)
@@ -367,6 +395,8 @@ jobs:
367395
-e "s/^PHP_VER=\"[^\"]*\"/PHP_VER=\"$(get_current_version PHP_VER)\"/" \
368396
-e "s/^PHPMYADMIN_VER=\"[^\"]*\"/PHPMYADMIN_VER=\"$(get_current_version PHPMYADMIN_VER)\"/" \
369397
-e "s/^ZLIB_VER=\"[^\"]*\"/ZLIB_VER=\"$(get_current_version ZLIB_VER)\"/" \
398+
-e "s/^ZLIB_NG_VER=\"[^\"]*\"/ZLIB_NG_VER=\"$(get_current_version ZLIB_NG_VER)\"/" \
399+
-e "s/^ZLIB_RS_VER=\"[^\"]*\"/ZLIB_RS_VER=\"$(get_current_version ZLIB_RS_VER)\"/" \
370400
-e "s/^SSE_PLUGIN_VER=\"[^\"]*\"/SSE_PLUGIN_VER=\"$(get_current_version SSE_PLUGIN_VER)\"/" \
371401
-e "s/^SWPO_PLUGIN_VER=\"[^\"]*\"/SWPO_PLUGIN_VER=\"$(get_current_version SWPO_PLUGIN_VER)\"/" \
372402
.github/ci-config/enginescript-variables-ci.txt

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ All notable changes to EngineScript will be documented in this file.
44

55
Changes are organized by date, with the most recent changes listed first.
66

7+
## 2026-02-26
8+
9+
### ⚗️ EXPERIMENTAL ZLIB ALTERNATIVES FOR NGINX
10+
11+
- **Added `ZLIB_IMPLEMENTATION` option** to `config/home/enginescript-install-options.txt`:
12+
- `""` (empty/default) = standard zlib (no change from current behavior)
13+
- `"zlib-ng"` = zlib-ng, a high-performance C drop-in replacement using `--zlib-compat` mode
14+
- `"zlib-rs"` = zlib-rs, a Rust-based implementation (requires cargo/rustc on the server)
15+
- **Added `ZLIB_NG_VER` and `ZLIB_RS_VER`** to `enginescript-variables.txt` for centralized version management.
16+
- **Updated `scripts/install/zlib/zlib-install.sh`**: Now prepares the selected zlib alternative alongside the standard zlib download. Handles zlib-ng configure wrapper, stub Makefile (for nginx distclean compatibility), and zlib-rs cargo build + prefix install.
17+
- **Updated `scripts/install/nginx/nginx-compile.sh`**: Dynamically sets `--with-zlib` flags or include/link paths based on `ZLIB_IMPLEMENTATION`. Appends a build tag (`-zlibng` or `-zlibrs`) to the nginx `--build` string for identification.
18+
719
## 2026-02-25
820

921
### �️ CLOUDFLARE ZLIB REMOVAL

config/home/enginescript-install-options.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,19 @@ SHOW_ENGINESCRIPT_HEADER=0
9292
# Disable if you need to access these files through the web (not recommended for security)
9393
NGINX_BLOCK_UNSAFE_FILES=0
9494

95+
## Experimental: zlib Alternative for Nginx (Optional) ##
96+
# Select an alternative zlib implementation for Nginx compilation.
97+
# This replaces the standard zlib with a higher-performance drop-in replacement.
98+
# Leave empty or set to "standard" to use official zlib (default, stable).
99+
#
100+
# Options:
101+
# "" = Standard zlib (default)
102+
# "zlib-ng" = zlib-ng (C, high-performance drop-in with --zlib-compat mode)
103+
# "zlib-rs" = zlib-rs (Rust-based, requires cargo/rustc toolchain on the server)
104+
#
105+
# WARNING: These are experimental options. If Nginx fails to compile, set back to "".
106+
ZLIB_IMPLEMENTATION=""
107+
95108
## DigitalOcean Remote Console ##
96109
# Install DigitalOcean's Droplet Agent for remote console access
97110
# This enables the Recovery Console feature in the DigitalOcean control panel

enginescript-variables.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ PHP_VER="8.5"
1818
PHPMYADMIN_VER="5.2.3"
1919
PNGOUT_VER="20200115"
2020
ZLIB_VER="1.3.2"
21+
ZLIB_NG_VER="2.3.3"
22+
ZLIB_RS_VER="v0.6.0"
2123

2224
# EngineScript Plugins
2325
SSE_PLUGIN_VER="1.9.1"

scripts/install/nginx/nginx-compile.sh

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,45 @@ fi
103103

104104
OPENSSL_OPT_FLAGS="enable-ec_nistp_64_gcc_128 enable-ktls no-deprecated no-psk no-srp no-ssl3-method no-tls1-method no-tls1_1-method no-weak-ssl-ciphers $OPENSSL_TESTS_FLAG"
105105

106+
# Determine zlib implementation flags for nginx configure
107+
ZLIB_CC_EXTRA=""
108+
ZLIB_LD_EXTRA=""
109+
ZLIB_CONFIGURE_FLAGS=()
110+
ZLIB_BUILD_TAG=""
111+
112+
case "${ZLIB_IMPLEMENTATION}" in
113+
zlib-ng)
114+
ZLIB_CONFIGURE_FLAGS=(
115+
--with-zlib="/usr/src/zlib-ng-${ZLIB_NG_VER}"
116+
--with-zlib-opt=-fPIC
117+
)
118+
ZLIB_BUILD_TAG="-zlibng"
119+
echo "Using zlib-ng ${ZLIB_NG_VER} for Nginx compilation"
120+
;;
121+
zlib-rs)
122+
ZLIB_RS_PREFIX="/opt/zlib-rs"
123+
ZLIB_CC_EXTRA="-I${ZLIB_RS_PREFIX}/include"
124+
ZLIB_LD_EXTRA="-L${ZLIB_RS_PREFIX}/lib"
125+
ZLIB_BUILD_TAG="-zlibrs"
126+
echo "Using zlib-rs ${ZLIB_RS_VER} for Nginx compilation"
127+
;;
128+
*)
129+
ZLIB_CONFIGURE_FLAGS=(
130+
--with-zlib="/usr/src/zlib-${ZLIB_VER}"
131+
--with-zlib-opt=-fPIC
132+
)
133+
echo "Using standard zlib ${ZLIB_VER} for Nginx compilation"
134+
;;
135+
esac
136+
137+
# Append zlib extras to compiler/linker flags
138+
if [[ -n "$ZLIB_CC_EXTRA" ]]; then
139+
CC_OPT_FLAGS="$CC_OPT_FLAGS $ZLIB_CC_EXTRA"
140+
fi
141+
if [[ -n "$ZLIB_LD_EXTRA" ]]; then
142+
LD_OPT_FLAGS="$LD_OPT_FLAGS $ZLIB_LD_EXTRA"
143+
fi
144+
106145
if [[ "${INSTALL_HTTP3}" == "1" ]];
107146
then
108147
# HTTP3
@@ -120,7 +159,7 @@ if [[ "${INSTALL_HTTP3}" == "1" ]];
120159
--modules-path=/etc/nginx/modules \
121160
--pid-path=/run/nginx.pid \
122161
--sbin-path=/usr/sbin/nginx \
123-
--build="nginx-${NGINX_VER}-${DT}-enginescript" \
162+
--build="nginx-${NGINX_VER}-${DT}-enginescript${ZLIB_BUILD_TAG}" \
124163
--builddir="nginx-${NGINX_VER}" \
125164
--with-cc-opt="$CC_OPT_FLAGS" \
126165
--with-ld-opt="$LD_OPT_FLAGS" \
@@ -131,8 +170,7 @@ if [[ "${INSTALL_HTTP3}" == "1" ]];
131170
--with-threads \
132171
--with-pcre="/usr/src/pcre2-${PCRE2_VER}" \
133172
--with-pcre-jit \
134-
--with-zlib="/usr/src/zlib-${ZLIB_VER}" \
135-
--with-zlib-opt=-fPIC \
173+
"${ZLIB_CONFIGURE_FLAGS[@]}" \
136174
--with-http_ssl_module \
137175
--with-http_v2_module \
138176
--with-http_v3_module \
@@ -167,7 +205,7 @@ if [[ "${INSTALL_HTTP3}" == "1" ]];
167205
--modules-path=/etc/nginx/modules \
168206
--pid-path=/run/nginx.pid \
169207
--sbin-path=/usr/sbin/nginx \
170-
--build="nginx-${NGINX_VER}-${DT}-enginescript" \
208+
--build="nginx-${NGINX_VER}-${DT}-enginescript${ZLIB_BUILD_TAG}" \
171209
--builddir="nginx-${NGINX_VER}" \
172210
--with-cc-opt="$CC_OPT_FLAGS" \
173211
--with-ld-opt="$LD_OPT_FLAGS" \
@@ -178,8 +216,7 @@ if [[ "${INSTALL_HTTP3}" == "1" ]];
178216
--with-threads \
179217
--with-pcre="/usr/src/pcre2-${PCRE2_VER}" \
180218
--with-pcre-jit \
181-
--with-zlib="/usr/src/zlib-${ZLIB_VER}" \
182-
--with-zlib-opt=-fPIC \
219+
"${ZLIB_CONFIGURE_FLAGS[@]}" \
183220
--with-http_ssl_module \
184221
--with-http_v2_module \
185222
--with-http_realip_module \

scripts/install/zlib/zlib-install.sh

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,103 @@ source /usr/local/bin/enginescript/scripts/functions/shared/enginescript-common.
2121
# Return to /usr/src
2222
cd /usr/src
2323

24-
# Official zlib Download
25-
# Remove existing official zlib source directory and tarball if they exist
24+
# Always download standard zlib (used as fallback and needed by default)
2625
clean_directory "/usr/src/zlib-${ZLIB_VER}"
2726
if [[ -f "/usr/src/zlib-${ZLIB_VER}.tar.gz" ]]; then
2827
rm -f "/usr/src/zlib-${ZLIB_VER}.tar.gz"
2928
fi
30-
3129
download_and_extract "https://github.com/madler/zlib/archive/refs/tags/v${ZLIB_VER}.tar.gz" "/usr/src/zlib-${ZLIB_VER}.tar.gz"
3230

31+
32+
#----------------------------------------------------------------------------------
33+
# Experimental: zlib-ng preparation
34+
35+
if [[ "${ZLIB_IMPLEMENTATION}" == "zlib-ng" ]]; then
36+
echo "============================================================="
37+
echo " Preparing zlib-ng ${ZLIB_NG_VER} (experimental)"
38+
echo "============================================================="
39+
40+
cd /usr/src
41+
42+
clean_directory "/usr/src/zlib-ng-${ZLIB_NG_VER}"
43+
if [[ -f "/usr/src/zlib-ng-${ZLIB_NG_VER}.tar.gz" ]]; then
44+
rm -f "/usr/src/zlib-ng-${ZLIB_NG_VER}.tar.gz"
45+
fi
46+
47+
download_and_extract "https://github.com/zlib-ng/zlib-ng/archive/refs/tags/${ZLIB_NG_VER}.tar.gz" "/usr/src/zlib-ng-${ZLIB_NG_VER}.tar.gz"
48+
49+
# Create a configure wrapper
50+
#
51+
# Nginx's build system calls ./configure with NO arguments in the zlib
52+
# source dir. zlib-ng REQUIRES --zlib-compat to produce a standard
53+
# zlib-compatible API (libz.a with standard symbol names).
54+
# Without it, zlib-ng produces libz-ng.a with zng_ prefixed symbols.
55+
#
56+
# Solution: rename the real configure and create a wrapper that always
57+
# passes --zlib-compat.
58+
cd "/usr/src/zlib-ng-${ZLIB_NG_VER}"
59+
mv configure configure.zlib-ng
60+
cat > configure << 'WRAPPER'
61+
#!/bin/sh
62+
exec "$(dirname "$0")/configure.zlib-ng" --zlib-compat "$@"
63+
WRAPPER
64+
chmod +x configure
65+
66+
# Stub Makefile so nginx's "make distclean" succeeds before configure runs.
67+
# Overwritten when ./configure generates the real Makefile.
68+
cat > Makefile << 'STUBMAKE'
69+
.PHONY: distclean clean
70+
distclean clean:
71+
@echo "stub: no-op (pre-configure)"
72+
STUBMAKE
73+
74+
echo "zlib-ng ${ZLIB_NG_VER} prepared for Nginx compilation"
75+
fi
76+
77+
78+
#----------------------------------------------------------------------------------
79+
# Experimental: zlib-rs preparation
80+
81+
if [[ "${ZLIB_IMPLEMENTATION}" == "zlib-rs" ]]; then
82+
echo "============================================================="
83+
echo " Preparing zlib-rs ${ZLIB_RS_VER} (experimental)"
84+
echo "============================================================="
85+
86+
ZLIB_RS_PREFIX="/opt/zlib-rs"
87+
88+
# Install Rust toolchain if not present
89+
if ! command -v cargo >/dev/null 2>&1; then
90+
echo "Installing Rust toolchain (required for zlib-rs)..."
91+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
92+
source "$HOME/.cargo/env"
93+
fi
94+
95+
echo "Rust version: $(rustc --version)"
96+
echo "Cargo version: $(cargo --version)"
97+
98+
cd /usr/src
99+
100+
clean_directory "/usr/src/zlib-rs"
101+
git clone --branch "${ZLIB_RS_VER}" --depth 1 https://github.com/trifectatechfoundation/zlib-rs.git /usr/src/zlib-rs
102+
103+
cd /usr/src/zlib-rs/libz-rs-sys-cdylib
104+
105+
# Build with native CPU optimizations for best performance
106+
RUSTFLAGS="-Ctarget-cpu=native -Cllvm-args=-enable-dfa-jump-thread" \
107+
cargo build --release --features c-allocator
108+
109+
echo "zlib-rs library built successfully"
110+
111+
# Install to a local prefix mimicking a standard zlib install
112+
rm -rf "${ZLIB_RS_PREFIX}"
113+
mkdir -p "${ZLIB_RS_PREFIX}/lib" "${ZLIB_RS_PREFIX}/include"
114+
115+
cp /usr/src/zlib-rs/target/release/libz_rs.a "${ZLIB_RS_PREFIX}/lib/libz.a"
116+
cp /usr/src/zlib-rs/libz-rs-sys-cdylib/include/zlib.h "${ZLIB_RS_PREFIX}/include/"
117+
cp /usr/src/zlib-rs/libz-rs-sys-cdylib/include/zconf.h "${ZLIB_RS_PREFIX}/include/"
118+
119+
echo "zlib-rs ${ZLIB_RS_VER} installed to ${ZLIB_RS_PREFIX}"
120+
fi
121+
33122
# Return to /usr/src
34123
cd /usr/src

0 commit comments

Comments
 (0)