From 70f33a772781233e289975fad9e05db53e070140 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 30 Oct 2025 10:11:16 +0000
Subject: [PATCH 1/7] Initial plan
From e046d8c0e0d4c811187b34d66a342bcd2e4471db Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 30 Oct 2025 10:15:14 +0000
Subject: [PATCH 2/7] Add comprehensive CI/CD workflow for zstd-nginx-module
Co-authored-by: tokers <10428333+tokers@users.noreply.github.com>
---
.github/workflows/ci.yml | 211 +++++++++++++++++++++++++++++++++++++++
1 file changed, 211 insertions(+)
create mode 100644 .github/workflows/ci.yml
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..0ff3f9c
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,211 @@
+name: CI
+
+on:
+ push:
+ branches: [ main, master ]
+ pull_request:
+ branches: [ main, master ]
+ workflow_dispatch:
+
+jobs:
+ test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-20.04, ubuntu-22.04]
+ nginx_version: ['1.24.0', '1.25.3', '1.26.0']
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y \
+ build-essential \
+ libpcre3 libpcre3-dev \
+ zlib1g zlib1g-dev \
+ libssl-dev \
+ libzstd-dev \
+ perl \
+ cpanminus
+
+ - name: Install Perl test dependencies
+ run: |
+ sudo cpanm --notest Test::Nginx
+
+ - name: Cache nginx
+ id: cache-nginx
+ uses: actions/cache@v4
+ with:
+ path: ~/nginx-${{ matrix.nginx_version }}
+ key: nginx-${{ matrix.nginx_version }}-${{ matrix.os }}
+
+ - name: Download and extract nginx
+ if: steps.cache-nginx.outputs.cache-hit != 'true'
+ run: |
+ cd ~
+ wget -q http://nginx.org/download/nginx-${{ matrix.nginx_version }}.tar.gz
+ tar -xzf nginx-${{ matrix.nginx_version }}.tar.gz
+
+ - name: Configure and build nginx with zstd module
+ run: |
+ cd ~/nginx-${{ matrix.nginx_version }}
+ ./configure \
+ --prefix=/tmp/nginx \
+ --with-http_ssl_module \
+ --with-http_v2_module \
+ --add-module=${{ github.workspace }}
+ make -j$(nproc)
+ sudo make install
+
+ - name: Add nginx to PATH
+ run: |
+ echo "/tmp/nginx/sbin" >> $GITHUB_PATH
+
+ - name: Verify nginx installation
+ run: |
+ /tmp/nginx/sbin/nginx -V
+
+ - name: Run tests
+ run: |
+ export PATH=/tmp/nginx/sbin:$PATH
+ cd ${{ github.workspace }}
+ prove -r t/
+ env:
+ TEST_NGINX_BINARY: /tmp/nginx/sbin/nginx
+
+ build-docker:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Build test Dockerfile
+ run: |
+ cat > Dockerfile.test << 'EOF'
+ FROM nginx:1.26.0 AS builder
+
+ # Install build dependencies
+ RUN apt-get update && apt-get install -y \
+ build-essential \
+ libpcre3-dev \
+ zlib1g-dev \
+ libssl-dev \
+ libzstd-dev \
+ wget \
+ && rm -rf /var/lib/apt/lists/*
+
+ # Get nginx source
+ WORKDIR /build
+ RUN wget -q http://nginx.org/download/nginx-1.26.0.tar.gz && \
+ tar -xzf nginx-1.26.0.tar.gz
+
+ # Copy module source
+ COPY . /build/zstd-nginx-module
+
+ # Build nginx with zstd module
+ WORKDIR /build/nginx-1.26.0
+ RUN ./configure \
+ --prefix=/etc/nginx \
+ --sbin-path=/usr/sbin/nginx \
+ --modules-path=/usr/lib/nginx/modules \
+ --conf-path=/etc/nginx/nginx.conf \
+ --error-log-path=/var/log/nginx/error.log \
+ --http-log-path=/var/log/nginx/access.log \
+ --pid-path=/var/run/nginx.pid \
+ --lock-path=/var/run/nginx.lock \
+ --http-client-body-temp-path=/var/cache/nginx/client_temp \
+ --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
+ --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
+ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
+ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
+ --user=nginx \
+ --group=nginx \
+ --with-http_ssl_module \
+ --with-http_realip_module \
+ --with-http_addition_module \
+ --with-http_sub_module \
+ --with-http_dav_module \
+ --with-http_flv_module \
+ --with-http_mp4_module \
+ --with-http_gunzip_module \
+ --with-http_gzip_static_module \
+ --with-http_random_index_module \
+ --with-http_secure_link_module \
+ --with-http_stub_status_module \
+ --with-http_auth_request_module \
+ --with-http_v2_module \
+ --with-http_slice_module \
+ --with-threads \
+ --with-file-aio \
+ --add-module=/build/zstd-nginx-module && \
+ make -j$(nproc) && \
+ make install
+
+ # Runtime stage
+ FROM nginx:1.26.0
+
+ # Install runtime dependencies
+ RUN apt-get update && apt-get install -y \
+ libzstd1 \
+ && rm -rf /var/lib/apt/lists/*
+
+ # Copy compiled nginx with zstd module
+ COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx
+
+ # Test configuration
+ RUN nginx -V 2>&1 | grep zstd
+
+ EXPOSE 80 443
+ CMD ["nginx", "-g", "daemon off;"]
+ EOF
+
+ - name: Build Docker image
+ run: |
+ docker build -f Dockerfile.test -t nginx-zstd:test .
+
+ - name: Test Docker image
+ run: |
+ # Start container
+ docker run -d --name nginx-zstd-test nginx-zstd:test
+ sleep 2
+
+ # Check if nginx is running
+ docker ps | grep nginx-zstd-test
+
+ # Check nginx version includes zstd
+ docker exec nginx-zstd-test nginx -V 2>&1 | grep zstd
+
+ # Cleanup
+ docker stop nginx-zstd-test
+ docker rm nginx-zstd-test
+
+ lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Check for trailing whitespace
+ run: |
+ if git grep -I --line-number -P '\s+$' -- '*.c' '*.h' 'config' 2>/dev/null; then
+ echo "Error: Found trailing whitespace"
+ exit 1
+ else
+ echo "No trailing whitespace found"
+ fi
+
+ - name: Check file permissions
+ run: |
+ # Check that source files don't have execute permissions
+ if find . -name '*.c' -o -name '*.h' | xargs ls -l | grep '^-rwxr'; then
+ echo "Error: Source files should not be executable"
+ exit 1
+ else
+ echo "File permissions are correct"
+ fi
From 25c03780ff36151661912c64d0976afeaaab3d37 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 30 Oct 2025 10:16:57 +0000
Subject: [PATCH 3/7] Add example configurations and Dockerfile for users
Co-authored-by: tokers <10428333+tokers@users.noreply.github.com>
---
example/Dockerfile | 97 ++++++++++++++++++++++++++++++
example/README.md | 147 +++++++++++++++++++++++++++++++++++++++++++++
example/nginx.conf | 69 +++++++++++++++++++++
3 files changed, 313 insertions(+)
create mode 100644 example/Dockerfile
create mode 100644 example/README.md
create mode 100644 example/nginx.conf
diff --git a/example/Dockerfile b/example/Dockerfile
new file mode 100644
index 0000000..ff33c9c
--- /dev/null
+++ b/example/Dockerfile
@@ -0,0 +1,97 @@
+# Multi-stage Dockerfile for building Nginx with zstd-nginx-module
+#
+# This Dockerfile demonstrates how to build a production-ready Nginx image
+# with the zstd compression module integrated.
+#
+# Usage:
+# docker build -t nginx-zstd:latest .
+# docker run -d -p 80:80 nginx-zstd:latest
+
+ARG NGINX_VERSION=1.26.0
+
+# Build stage
+FROM nginx:${NGINX_VERSION} AS builder
+
+# Install build dependencies
+RUN apt-get update && apt-get install -y \
+ build-essential \
+ libpcre3-dev \
+ zlib1g-dev \
+ libssl-dev \
+ libzstd-dev \
+ wget \
+ && rm -rf /var/lib/apt/lists/*
+
+# Download and extract Nginx source
+WORKDIR /build
+RUN wget -q http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz && \
+ tar -xzf nginx-${NGINX_VERSION}.tar.gz
+
+# Copy zstd-nginx-module source
+COPY . /build/zstd-nginx-module
+
+# Configure and build Nginx with zstd module
+WORKDIR /build/nginx-${NGINX_VERSION}
+RUN ./configure \
+ --prefix=/etc/nginx \
+ --sbin-path=/usr/sbin/nginx \
+ --modules-path=/usr/lib/nginx/modules \
+ --conf-path=/etc/nginx/nginx.conf \
+ --error-log-path=/var/log/nginx/error.log \
+ --http-log-path=/var/log/nginx/access.log \
+ --pid-path=/var/run/nginx.pid \
+ --lock-path=/var/run/nginx.lock \
+ --http-client-body-temp-path=/var/cache/nginx/client_temp \
+ --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
+ --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
+ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
+ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
+ --user=nginx \
+ --group=nginx \
+ --with-http_ssl_module \
+ --with-http_realip_module \
+ --with-http_addition_module \
+ --with-http_sub_module \
+ --with-http_dav_module \
+ --with-http_flv_module \
+ --with-http_mp4_module \
+ --with-http_gunzip_module \
+ --with-http_gzip_static_module \
+ --with-http_random_index_module \
+ --with-http_secure_link_module \
+ --with-http_stub_status_module \
+ --with-http_auth_request_module \
+ --with-http_v2_module \
+ --with-http_slice_module \
+ --with-threads \
+ --with-file-aio \
+ --add-module=/build/zstd-nginx-module && \
+ make -j$(nproc) && \
+ make install
+
+# Runtime stage
+FROM nginx:${NGINX_VERSION}
+
+# Install runtime dependencies
+RUN apt-get update && apt-get install -y \
+ libzstd1 \
+ && rm -rf /var/lib/apt/lists/*
+
+# Copy compiled Nginx binary with zstd module
+COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx
+
+# Copy example configuration (optional)
+COPY example/nginx.conf /etc/nginx/nginx.conf.example
+
+# Verify the module is loaded
+RUN nginx -V 2>&1 | grep -q zstd || (echo "zstd module not found!" && exit 1)
+
+# Expose ports
+EXPOSE 80 443
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
+ CMD curl -f http://localhost/ || exit 1
+
+# Start Nginx
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/example/README.md b/example/README.md
new file mode 100644
index 0000000..4ef1a4a
--- /dev/null
+++ b/example/README.md
@@ -0,0 +1,147 @@
+# Examples
+
+This directory contains example configurations and Dockerfiles for using the zstd-nginx-module.
+
+## Contents
+
+- `nginx.conf` - Example Nginx configuration with zstd compression enabled
+- `Dockerfile` - Multi-stage Dockerfile for building Nginx with zstd module
+
+## Using the Dockerfile
+
+Build the Docker image:
+
+```bash
+docker build -t nginx-zstd:latest .
+```
+
+Run the container:
+
+```bash
+docker run -d -p 80:80 --name nginx-zstd nginx-zstd:latest
+```
+
+Test zstd compression:
+
+```bash
+# Request with zstd accept-encoding
+curl -H "Accept-Encoding: zstd" -I http://localhost/
+
+# You should see "Content-Encoding: zstd" in the response headers
+```
+
+## Using the nginx.conf
+
+The example configuration demonstrates:
+
+1. **Basic zstd compression** - Enabled globally with compression level 3
+2. **Compression thresholds** - Only compress responses larger than 256 bytes
+3. **MIME type filtering** - Compress specific content types
+4. **Static pre-compressed files** - Serve `.zst` files when available
+5. **Logging compression ratio** - Track compression efficiency with `$zstd_ratio` variable
+
+To use this configuration:
+
+1. Copy it to your Nginx configuration directory:
+ ```bash
+ cp nginx.conf /etc/nginx/nginx.conf
+ ```
+
+2. Test the configuration:
+ ```bash
+ nginx -t
+ ```
+
+3. Reload Nginx:
+ ```bash
+ nginx -s reload
+ ```
+
+## Building Nginx Manually
+
+If you prefer to build Nginx manually without Docker:
+
+```bash
+# Install dependencies
+sudo apt-get install -y build-essential libpcre3-dev zlib1g-dev libssl-dev libzstd-dev
+
+# Download Nginx source
+wget http://nginx.org/download/nginx-1.26.0.tar.gz
+tar -xzf nginx-1.26.0.tar.gz
+cd nginx-1.26.0
+
+# Configure with zstd module
+./configure --prefix=/usr/local/nginx \
+ --with-http_ssl_module \
+ --with-http_v2_module \
+ --add-module=/path/to/zstd-nginx-module
+
+# Build and install
+make -j$(nproc)
+sudo make install
+```
+
+## Testing Compression
+
+After setting up Nginx with zstd module, you can test compression:
+
+```bash
+# Create a test HTML file
+echo "
Hello World
$(yes 'Test content ' | head -1000)" > /usr/share/nginx/html/test.html
+
+# Request without compression
+curl -H "Accept-Encoding:" http://localhost/test.html -o /tmp/uncompressed.html
+
+# Request with zstd compression
+curl -H "Accept-Encoding: zstd" http://localhost/test.html --compressed -o /tmp/compressed.html
+
+# Compare sizes
+ls -lh /tmp/uncompressed.html /tmp/compressed.html
+```
+
+## Advanced Configuration
+
+### Using Zstd Dictionary
+
+For even better compression ratios, you can use a pre-trained dictionary:
+
+```nginx
+http {
+ # Specify dictionary file
+ zstd_dict_file /etc/nginx/zstd_dict.bin;
+
+ # ... rest of configuration
+}
+```
+
+**Warning**: Both client and server must use the same dictionary. Ensure clients support your dictionary before enabling this feature.
+
+### Static Pre-compressed Files
+
+To serve pre-compressed `.zst` files:
+
+```bash
+# Pre-compress static files
+zstd -k -19 /usr/share/nginx/html/large-file.js
+
+# This creates large-file.js.zst
+```
+
+Nginx will automatically serve the `.zst` version when `zstd_static on;` is configured and the client supports zstd encoding.
+
+## Performance Tips
+
+1. **Compression Level**: Use levels 1-3 for dynamic content, 10-19 for static files
+2. **Minimum Length**: Set `zstd_min_length` to avoid compressing small files
+3. **MIME Types**: Only compress compressible content types
+4. **Static Pre-compression**: Pre-compress static assets at build time
+5. **Buffer Size**: Adjust `zstd_buffers` based on your content size
+
+## Browser Support
+
+Zstd compression is supported by:
+- Chrome/Edge 123+
+- Firefox 126+
+- Safari (partial support)
+
+Always include fallback compression methods (gzip, brotli) for broader compatibility.
diff --git a/example/nginx.conf b/example/nginx.conf
new file mode 100644
index 0000000..d12fcd1
--- /dev/null
+++ b/example/nginx.conf
@@ -0,0 +1,69 @@
+# Example Nginx Configuration with zstd-nginx-module
+
+user nginx;
+worker_processes auto;
+
+error_log /var/log/nginx/error.log notice;
+pid /var/run/nginx.pid;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ '$status $body_bytes_sent "$http_referer" '
+ '"$http_user_agent" "$http_x_forwarded_for" '
+ 'zstd_ratio:$zstd_ratio';
+
+ access_log /var/log/nginx/access.log main;
+
+ sendfile on;
+ keepalive_timeout 65;
+
+ # Enable zstd compression globally
+ zstd on;
+ zstd_comp_level 3;
+ zstd_min_length 256;
+ zstd_types
+ text/plain
+ text/css
+ text/xml
+ text/javascript
+ application/json
+ application/javascript
+ application/xml+rss
+ application/rss+xml
+ application/atom+xml
+ image/svg+xml
+ application/x-font-ttf
+ application/x-font-opentype
+ application/vnd.ms-fontobject;
+
+ server {
+ listen 80;
+ server_name localhost;
+
+ location / {
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+
+ # Enable zstd compression for this location
+ zstd on;
+ }
+
+ location /static/ {
+ # Serve pre-compressed .zst files if they exist
+ zstd_static on;
+ root /usr/share/nginx/html;
+ }
+
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root /usr/share/nginx/html;
+ }
+ }
+}
From a2dc043a414c234c2310fe393f7f4cd9a8840f5c Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 30 Oct 2025 10:19:52 +0000
Subject: [PATCH 4/7] Fix YAML formatting in CI workflow
Co-authored-by: tokers <10428333+tokers@users.noreply.github.com>
---
.github/workflows/ci.yml | 373 ++++++++++++++++++++-------------------
1 file changed, 188 insertions(+), 185 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0ff3f9c..ec9883e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,9 +2,9 @@ name: CI
on:
push:
- branches: [ main, master ]
+ branches: [main, master]
pull_request:
- branches: [ main, master ]
+ branches: [main, master]
workflow_dispatch:
jobs:
@@ -15,197 +15,200 @@ jobs:
matrix:
os: [ubuntu-20.04, ubuntu-22.04]
nginx_version: ['1.24.0', '1.25.3', '1.26.0']
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Install dependencies
- run: |
- sudo apt-get update
- sudo apt-get install -y \
- build-essential \
- libpcre3 libpcre3-dev \
- zlib1g zlib1g-dev \
- libssl-dev \
- libzstd-dev \
- perl \
- cpanminus
-
- - name: Install Perl test dependencies
- run: |
- sudo cpanm --notest Test::Nginx
-
- - name: Cache nginx
- id: cache-nginx
- uses: actions/cache@v4
- with:
- path: ~/nginx-${{ matrix.nginx_version }}
- key: nginx-${{ matrix.nginx_version }}-${{ matrix.os }}
-
- - name: Download and extract nginx
- if: steps.cache-nginx.outputs.cache-hit != 'true'
- run: |
- cd ~
- wget -q http://nginx.org/download/nginx-${{ matrix.nginx_version }}.tar.gz
- tar -xzf nginx-${{ matrix.nginx_version }}.tar.gz
-
- - name: Configure and build nginx with zstd module
- run: |
- cd ~/nginx-${{ matrix.nginx_version }}
- ./configure \
- --prefix=/tmp/nginx \
- --with-http_ssl_module \
- --with-http_v2_module \
- --add-module=${{ github.workspace }}
- make -j$(nproc)
- sudo make install
-
- - name: Add nginx to PATH
- run: |
- echo "/tmp/nginx/sbin" >> $GITHUB_PATH
-
- - name: Verify nginx installation
- run: |
- /tmp/nginx/sbin/nginx -V
-
- - name: Run tests
- run: |
- export PATH=/tmp/nginx/sbin:$PATH
- cd ${{ github.workspace }}
- prove -r t/
- env:
- TEST_NGINX_BINARY: /tmp/nginx/sbin/nginx
- build-docker:
- runs-on: ubuntu-latest
-
steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Build test Dockerfile
- run: |
- cat > Dockerfile.test << 'EOF'
- FROM nginx:1.26.0 AS builder
-
- # Install build dependencies
- RUN apt-get update && apt-get install -y \
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y \
build-essential \
- libpcre3-dev \
- zlib1g-dev \
+ libpcre3 libpcre3-dev \
+ zlib1g zlib1g-dev \
libssl-dev \
libzstd-dev \
- wget \
- && rm -rf /var/lib/apt/lists/*
-
- # Get nginx source
- WORKDIR /build
- RUN wget -q http://nginx.org/download/nginx-1.26.0.tar.gz && \
- tar -xzf nginx-1.26.0.tar.gz
-
- # Copy module source
- COPY . /build/zstd-nginx-module
-
- # Build nginx with zstd module
- WORKDIR /build/nginx-1.26.0
- RUN ./configure \
- --prefix=/etc/nginx \
- --sbin-path=/usr/sbin/nginx \
- --modules-path=/usr/lib/nginx/modules \
- --conf-path=/etc/nginx/nginx.conf \
- --error-log-path=/var/log/nginx/error.log \
- --http-log-path=/var/log/nginx/access.log \
- --pid-path=/var/run/nginx.pid \
- --lock-path=/var/run/nginx.lock \
- --http-client-body-temp-path=/var/cache/nginx/client_temp \
- --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
- --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
- --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
- --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
- --user=nginx \
- --group=nginx \
+ perl \
+ cpanminus
+
+ - name: Install Perl test dependencies
+ run: |
+ sudo cpanm --notest Test::Nginx
+
+ - name: Cache nginx
+ id: cache-nginx
+ uses: actions/cache@v4
+ with:
+ path: ~/nginx-${{ matrix.nginx_version }}
+ key: nginx-${{ matrix.nginx_version }}-${{ matrix.os }}
+
+ - name: Download and extract nginx
+ if: steps.cache-nginx.outputs.cache-hit != 'true'
+ run: |
+ cd ~
+ NGINX_VERSION="${{ matrix.nginx_version }}"
+ wget -q "http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz"
+ tar -xzf "nginx-${NGINX_VERSION}.tar.gz"
+
+ - name: Configure and build nginx with zstd module
+ run: |
+ cd ~/nginx-${{ matrix.nginx_version }}
+ ./configure \
+ --prefix=/tmp/nginx \
--with-http_ssl_module \
- --with-http_realip_module \
- --with-http_addition_module \
- --with-http_sub_module \
- --with-http_dav_module \
- --with-http_flv_module \
- --with-http_mp4_module \
- --with-http_gunzip_module \
- --with-http_gzip_static_module \
- --with-http_random_index_module \
- --with-http_secure_link_module \
- --with-http_stub_status_module \
- --with-http_auth_request_module \
--with-http_v2_module \
- --with-http_slice_module \
- --with-threads \
- --with-file-aio \
- --add-module=/build/zstd-nginx-module && \
- make -j$(nproc) && \
- make install
-
- # Runtime stage
- FROM nginx:1.26.0
-
- # Install runtime dependencies
- RUN apt-get update && apt-get install -y \
- libzstd1 \
- && rm -rf /var/lib/apt/lists/*
-
- # Copy compiled nginx with zstd module
- COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx
-
- # Test configuration
- RUN nginx -V 2>&1 | grep zstd
-
- EXPOSE 80 443
- CMD ["nginx", "-g", "daemon off;"]
- EOF
-
- - name: Build Docker image
- run: |
- docker build -f Dockerfile.test -t nginx-zstd:test .
-
- - name: Test Docker image
- run: |
- # Start container
- docker run -d --name nginx-zstd-test nginx-zstd:test
- sleep 2
-
- # Check if nginx is running
- docker ps | grep nginx-zstd-test
-
- # Check nginx version includes zstd
- docker exec nginx-zstd-test nginx -V 2>&1 | grep zstd
-
- # Cleanup
- docker stop nginx-zstd-test
- docker rm nginx-zstd-test
+ --add-module=${{ github.workspace }}
+ make -j$(nproc)
+ sudo make install
+
+ - name: Add nginx to PATH
+ run: |
+ echo "/tmp/nginx/sbin" >> $GITHUB_PATH
+
+ - name: Verify nginx installation
+ run: |
+ /tmp/nginx/sbin/nginx -V
+
+ - name: Run tests
+ run: |
+ export PATH=/tmp/nginx/sbin:$PATH
+ cd ${{ github.workspace }}
+ prove -r t/
+ env:
+ TEST_NGINX_BINARY: /tmp/nginx/sbin/nginx
+
+ build-docker:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Build test Dockerfile
+ run: |
+ cat > Dockerfile.test << 'EOF'
+ FROM nginx:1.26.0 AS builder
+
+ # Install build dependencies
+ RUN apt-get update && apt-get install -y \
+ build-essential \
+ libpcre3-dev \
+ zlib1g-dev \
+ libssl-dev \
+ libzstd-dev \
+ wget \
+ && rm -rf /var/lib/apt/lists/*
+
+ # Get nginx source
+ WORKDIR /build
+ RUN wget -q http://nginx.org/download/nginx-1.26.0.tar.gz && \
+ tar -xzf nginx-1.26.0.tar.gz
+
+ # Copy module source
+ COPY . /build/zstd-nginx-module
+
+ # Build nginx with zstd module
+ WORKDIR /build/nginx-1.26.0
+ RUN ./configure \
+ --prefix=/etc/nginx \
+ --sbin-path=/usr/sbin/nginx \
+ --modules-path=/usr/lib/nginx/modules \
+ --conf-path=/etc/nginx/nginx.conf \
+ --error-log-path=/var/log/nginx/error.log \
+ --http-log-path=/var/log/nginx/access.log \
+ --pid-path=/var/run/nginx.pid \
+ --lock-path=/var/run/nginx.lock \
+ --http-client-body-temp-path=/var/cache/nginx/client_temp \
+ --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
+ --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
+ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
+ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
+ --user=nginx \
+ --group=nginx \
+ --with-http_ssl_module \
+ --with-http_realip_module \
+ --with-http_addition_module \
+ --with-http_sub_module \
+ --with-http_dav_module \
+ --with-http_flv_module \
+ --with-http_mp4_module \
+ --with-http_gunzip_module \
+ --with-http_gzip_static_module \
+ --with-http_random_index_module \
+ --with-http_secure_link_module \
+ --with-http_stub_status_module \
+ --with-http_auth_request_module \
+ --with-http_v2_module \
+ --with-http_slice_module \
+ --with-threads \
+ --with-file-aio \
+ --add-module=/build/zstd-nginx-module && \
+ make -j$(nproc) && \
+ make install
+
+ # Runtime stage
+ FROM nginx:1.26.0
+
+ # Install runtime dependencies
+ RUN apt-get update && apt-get install -y \
+ libzstd1 \
+ && rm -rf /var/lib/apt/lists/*
+
+ # Copy compiled nginx with zstd module
+ COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx
+
+ # Test configuration
+ RUN nginx -V 2>&1 | grep zstd
+
+ EXPOSE 80 443
+ CMD ["nginx", "-g", "daemon off;"]
+ EOF
+
+ - name: Build Docker image
+ run: |
+ docker build -f Dockerfile.test -t nginx-zstd:test .
+
+ - name: Test Docker image
+ run: |
+ # Start container
+ docker run -d --name nginx-zstd-test nginx-zstd:test
+ sleep 2
+
+ # Check if nginx is running
+ docker ps | grep nginx-zstd-test
+
+ # Check nginx version includes zstd
+ docker exec nginx-zstd-test nginx -V 2>&1 | grep zstd
+
+ # Cleanup
+ docker stop nginx-zstd-test
+ docker rm nginx-zstd-test
lint:
runs-on: ubuntu-latest
-
+
steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Check for trailing whitespace
- run: |
- if git grep -I --line-number -P '\s+$' -- '*.c' '*.h' 'config' 2>/dev/null; then
- echo "Error: Found trailing whitespace"
- exit 1
- else
- echo "No trailing whitespace found"
- fi
-
- - name: Check file permissions
- run: |
- # Check that source files don't have execute permissions
- if find . -name '*.c' -o -name '*.h' | xargs ls -l | grep '^-rwxr'; then
- echo "Error: Source files should not be executable"
- exit 1
- else
- echo "File permissions are correct"
- fi
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Check for trailing whitespace
+ run: |
+ if git grep -I --line-number -P '\s+$' -- '*.c' '*.h' 'config' \
+ 2>/dev/null; then
+ echo "Error: Found trailing whitespace"
+ exit 1
+ else
+ echo "No trailing whitespace found"
+ fi
+
+ - name: Check file permissions
+ run: |
+ # Check that source files don't have execute permissions
+ if find . -name '*.c' -o -name '*.h' | xargs ls -l \
+ | grep '^-rwxr'; then
+ echo "Error: Source files should not be executable"
+ exit 1
+ else
+ echo "File permissions are correct"
+ fi
From b33ebb12eafecc98fa38f4aef47e0620bea0c4ca Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 30 Oct 2025 10:20:49 +0000
Subject: [PATCH 5/7] Add CI badge and Docker installation guide to README
Co-authored-by: tokers <10428333+tokers@users.noreply.github.com>
---
README.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/README.md b/README.md
index 6105896..846f350 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,7 @@
# Name
+
+[](https://github.com/tokers/zstd-nginx-module/actions/workflows/ci.yml)
+
zstd-nginx-module - Nginx module for the [Zstandard compression](https://facebook.github.io/zstd/).
# Table of Contents
@@ -67,6 +70,17 @@ To use theses modules, configure your nginx branch with `--add-module=/path/to/z
* System's zstd bundle will be linked if `ZSTD_INC` and `ZSTD_LIB` are not specified.
* Both `ngx_http_zstd_static_module` and `ngx_http_zstd_filter_module` will be configured.
+## Docker Installation
+
+A Dockerfile and example configuration are provided in the `example/` directory for easy containerized deployment:
+
+```bash
+docker build -f example/Dockerfile -t nginx-zstd:latest .
+docker run -d -p 80:80 nginx-zstd:latest
+```
+
+See the [example README](example/README.md) for more details on Docker deployment and configuration examples.
+
# Directives
## ngx_http_zstd_filter_module
From c16956ba94e719fd95c6747a617849430bb2cf40 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 30 Oct 2025 10:22:28 +0000
Subject: [PATCH 6/7] Add CI/CD implementation documentation
Co-authored-by: tokers <10428333+tokers@users.noreply.github.com>
---
CI_CD_IMPLEMENTATION.md | 170 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 170 insertions(+)
create mode 100644 CI_CD_IMPLEMENTATION.md
diff --git a/CI_CD_IMPLEMENTATION.md b/CI_CD_IMPLEMENTATION.md
new file mode 100644
index 0000000..7d9e13c
--- /dev/null
+++ b/CI_CD_IMPLEMENTATION.md
@@ -0,0 +1,170 @@
+# CI/CD Implementation Summary
+
+This document describes the CI/CD implementation for the zstd-nginx-module project.
+
+## Overview
+
+A comprehensive GitHub Actions CI/CD pipeline has been implemented to automatically build and test the zstd-nginx-module with various nginx versions and operating systems.
+
+## Workflow File
+
+Location: `.github/workflows/ci.yml`
+
+## CI/CD Features
+
+### 1. Test Job
+
+The main test job builds nginx with the zstd module and runs the test suite:
+
+**Matrix Testing:**
+- **Operating Systems:** Ubuntu 20.04, Ubuntu 22.04
+- **Nginx Versions:** 1.24.0, 1.25.3, 1.26.0
+- **Total Combinations:** 6 test configurations
+
+**Steps:**
+1. Checkout code
+2. Install system dependencies (build tools, libzstd, perl, etc.)
+3. Install Perl test dependencies (Test::Nginx)
+4. Cache nginx source for faster builds
+5. Download and extract nginx source (if not cached)
+6. Configure nginx with zstd module using `--add-module`
+7. Build nginx
+8. Install nginx
+9. Verify installation
+10. Run test suite with `prove -r t/`
+
+### 2. Docker Build Job
+
+Tests building a Docker image with nginx and zstd module:
+
+**Steps:**
+1. Creates a multi-stage Dockerfile for optimal image size
+2. Builds nginx with zstd module in builder stage
+3. Copies compiled binary to runtime stage
+4. Verifies the module is properly integrated
+5. Tests the container runs correctly
+
+### 3. Lint Job
+
+Performs basic code quality checks:
+
+**Checks:**
+- Trailing whitespace in source files
+- Incorrect file permissions on source files
+
+## Example Files
+
+Three example files have been added to help users:
+
+### 1. `example/nginx.conf`
+
+Complete nginx configuration demonstrating:
+- Global zstd compression settings
+- Compression level configuration
+- Minimum length thresholds
+- MIME type filtering
+- Static pre-compressed file serving
+- Compression ratio logging
+
+### 2. `example/Dockerfile`
+
+Production-ready multi-stage Dockerfile showing:
+- How to build nginx with zstd module
+- Proper dependency installation
+- Optimized layer caching
+- Runtime image preparation
+- Health checks
+
+### 3. `example/README.md`
+
+Comprehensive documentation covering:
+- Docker usage instructions
+- Manual build process
+- Configuration examples
+- Testing compression
+- Performance tips
+- Browser compatibility notes
+
+## Documentation Updates
+
+### README.md
+
+Added:
+- CI status badge showing workflow status
+- Docker installation section with quick start
+- Link to example documentation
+
+## Workflow Triggers
+
+The CI workflow runs on:
+- Push to `main` or `master` branches
+- Pull requests to `main` or `master` branches
+- Manual workflow dispatch
+
+## Caching Strategy
+
+The workflow uses GitHub Actions cache to speed up builds:
+- **Cached:** nginx source code by version and OS
+- **Benefits:** Faster subsequent builds, reduced network usage
+
+## Testing
+
+The test suite uses the Test::Nginx framework which:
+- Starts temporary nginx instances
+- Tests module functionality
+- Validates configuration options
+- Ensures proper compression behavior
+
+## Status
+
+✅ CI/CD workflow created and validated
+✅ YAML syntax verified with yamllint
+✅ Example configurations provided
+✅ Documentation updated
+⏳ Workflow pending approval (common for new workflows)
+
+## Next Steps for Users
+
+1. **Repository Maintainer:** Approve the workflow run in GitHub Actions
+2. **Review Results:** Check the workflow runs to ensure all tests pass
+3. **Customize:** Adjust nginx versions or OS versions as needed
+4. **Extend:** Add more test cases or additional checks
+
+## Maintenance
+
+To update the CI/CD:
+
+### Add a New Nginx Version
+
+Edit `.github/workflows/ci.yml`:
+```yaml
+matrix:
+ nginx_version: ['1.24.0', '1.25.3', '1.26.0', '1.27.0'] # Add new version
+```
+
+### Add a New OS Version
+
+Edit `.github/workflows/ci.yml`:
+```yaml
+matrix:
+ os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04] # Add new OS
+```
+
+### Add More Tests
+
+Add new test files to the `t/` directory following the Test::Nginx format.
+
+## Benefits
+
+1. **Automated Testing:** Every change is automatically tested
+2. **Multi-Version Support:** Ensures compatibility across nginx versions
+3. **Quality Assurance:** Catches build and test failures early
+4. **Documentation:** Examples help users get started quickly
+5. **Visibility:** CI badge shows project health at a glance
+
+## Resources
+
+- [GitHub Actions Documentation](https://docs.github.com/en/actions)
+- [Test::Nginx Documentation](https://metacpan.org/pod/Test::Nginx::Socket)
+- [Nginx Module Development](https://nginx.org/en/docs/dev/development_guide.html)
+- [Zstandard Compression](https://facebook.github.io/zstd/)
From c86652c96bc94d1f6aaf8b5986c9a146e4e178d7 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 30 Oct 2025 10:25:13 +0000
Subject: [PATCH 7/7] Add explicit GITHUB_TOKEN permissions for security
Co-authored-by: tokers <10428333+tokers@users.noreply.github.com>
---
.github/workflows/ci.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ec9883e..3b1f51a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,6 +7,9 @@ on:
branches: [main, master]
workflow_dispatch:
+permissions:
+ contents: read
+
jobs:
test:
runs-on: ${{ matrix.os }}