diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..2d2ecd6
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1 @@
+.git/
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7c99b8f..6dffc1a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
env:
- TAGS: 1.23.3,latest
+ NGINX_VERSION: 1.25.2
steps:
- uses: actions/checkout@v2
@@ -22,31 +22,25 @@ jobs:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
with:
registry: docker.io
- username: ${{ secrets.DOCKERHUB_USER }}
+ username: zengxs
password: ${{ secrets.DOCKERHUB_TOKEN }}
- - name: docker login to ghcr.io
- uses: docker/login-action@v2
- if: github.event_name == 'push' && github.ref == 'refs/heads/main'
- with:
- registry: ghcr.io
- username: ${{ github.repository_owner }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- name: Setup binfmt-support
- uses: docker/setup-qemu-action@v2
+ uses: docker/setup-qemu-action@v3
- name: Setup docker buildx
- uses: docker/setup-buildx-action@v2
+ uses: docker/setup-buildx-action@v3
- name: Generate push tags
- run: |
- dockerhub_tags=$(echo $TAGS | tr ',' '\n' | sed -e 's#^#docker.io/${{ secrets.DOCKERHUB_USER }}/nginx-quic:#g' | tr '\n' ',' | sed 's#,$##')
- ghcr_tags=$(echo $TAGS | tr ',' '\n' | sed -e 's#^#ghcr.io/nginx-quic/nginx-quic:#g' | tr '\n' ',' | sed 's#,$##')
- echo "PUSH_TAGS=${dockerhub_tags},${ghcr_tags}" >> $GITHUB_ENV
+ run: >-
+ python3 .github/workflows/generate-tags.py
+ --image-name docker.io/zengxs/nginx
+ --nginx-version ${{ env.NGINX_VERSION }}
+ --env-name PUSH_TAGS
+ >> $GITHUB_ENV
- name: Build and push
- uses: docker/build-push-action@v3
+ uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
@@ -54,3 +48,5 @@ jobs:
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
+ build-args: |
+ NGINX_VERSION=${{ env.NGINX_VERSION }}
diff --git a/.github/workflows/generate-tags.py b/.github/workflows/generate-tags.py
new file mode 100755
index 0000000..435b295
--- /dev/null
+++ b/.github/workflows/generate-tags.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python3
+
+import argparse
+from datetime import datetime
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--image-name", dest="image_name", required=True)
+ parser.add_argument("--nginx-version", dest="version", required=True)
+ parser.add_argument("--env-name", dest="env_name", required=True)
+ args = parser.parse_args()
+
+ tags = ["latest", args.version, datetime.today().strftime("%Y%m%d")]
+
+ final_tags = [f"{args.image_name}:{tag}" for tag in tags]
+ print("{}={}".format(args.env_name, ",".join(final_tags)))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/.gitmodules b/.gitmodules
index b591a0f..418f483 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,18 +1,12 @@
-[submodule "nginx-quic"]
- path = nginx-quic
- url = https://github.com/nginx-quic/nginx-quic.git
-[submodule "libressl"]
- path = libressl
- url = https://github.com/libressl-portable/portable.git
+[submodule "nginx"]
+ path = nginx
+ url = https://github.com/nginx/nginx.git
[submodule "modules/ngx_brotli"]
path = modules/ngx_brotli
url = https://github.com/google/ngx_brotli.git
[submodule "modules/njs"]
path = modules/njs
url = https://github.com/nginx/njs.git
-[submodule "modules/zstd-nginx-module"]
- path = modules/zstd-nginx-module
- url = https://github.com/tokers/zstd-nginx-module.git
[submodule "modules/nginx-module-vts"]
path = modules/nginx-module-vts
url = https://github.com/vozlt/nginx-module-vts.git
@@ -31,3 +25,6 @@
[submodule "modules/ngx-fancyindex"]
path = modules/ngx-fancyindex
url = https://github.com/aperezdc/ngx-fancyindex.git
+[submodule "modules/njs-acme"]
+ path = modules/njs-acme
+ url = https://github.com/nginx/njs-acme.git
diff --git a/Dockerfile b/Dockerfile
index ba120f3..64dac29 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-ARG NGINX_VERSION=1.23.3
+ARG NGINX_VERSION=1.25.2
# ==================================================================================================== #
FROM nginx:${NGINX_VERSION} AS builder
@@ -15,64 +15,24 @@ RUN set -ex \
autoconf \
libtool \
ca-certificates \
- curl
-
-# build libressl (instead of openssl for QUIC support)
-COPY ./libressl /usr/src/libressl
-RUN set -ex \
- && cd /usr/src/libressl \
- && ./autogen.sh \
- && ./configure \
- --prefix=/opt/libressl \
- --disable-tests \
- --enable-shared=yes \
- --enable-static=no \
- && make -j$(nproc) install_sw \
-# copy dynamic libraries to /usr/lib so nginx can find them
- && find /opt/libressl/lib -name '*.so.*' -exec cp -P {} /usr/lib \;
-
-# install build dependencies for nginx-quic
-RUN set -ex \
- && apt-get install -y --no-install-recommends \
+ curl \
+ libssl-dev \
libpcre3-dev \
zlib1g-dev
-# build nginx-quic
-COPY ./nginx-quic /usr/src/nginx-quic
-RUN set -ex \
- && cd /usr/src/nginx-quic \
- && echo ./auto/configure \
-# use the same configure arguments as the official nginx build
- $( \
- /usr/sbin/nginx -V 2>&1 \
- | grep 'configure arguments:' \
- | sed 's#.*arguments: ##' \
-# but use libressl instead of openssl for QUIC
- | sed "s#--with-cc-opt='#--with-cc-opt='-I/opt/libressl/include #" \
- | sed "s#--with-ld-opt='#--with-ld-opt='-L/opt/libressl/lib #" \
- ) \
-# add HTTP/3 and QUIC support
- --with-http_v3_module \
- --with-stream_quic_module \
- | bash -x \
-# build nginx
- && make -j$(nproc) \
-# just replace /usr/sbin/nginx with the new binary
- && cp ./objs/nginx /usr/sbin/nginx
-
# install build dependencies for additional dynamic modules
RUN set -ex \
&& apt-get install -y --no-install-recommends \
+ libedit-dev \
libgd-dev \
libgeoip-dev \
libmaxminddb-dev \
- libxslt1-dev \
- libzstd-dev
+ libxslt1-dev
-# build dynamic modules
+# copy dynamic modules source code
+COPY ./nginx /usr/src/nginx
COPY ./modules/njs /usr/src/njs
COPY ./modules/ngx_brotli /usr/src/ngx_brotli
-COPY ./modules/zstd-nginx-module /usr/src/zstd-nginx-module
COPY ./modules/nginx-module-vts /usr/src/nginx-module-vts
COPY ./modules/ngx_http_geoip2_module \
/usr/src/ngx_http_geoip2_module
@@ -81,8 +41,9 @@ COPY ./modules/ngx_http_substitutions_filter_module \
/usr/src/ngx_http_substitutions_filter_module
COPY ./modules/headers-more-nginx-module \
/usr/src/headers-more-nginx-module
+
RUN set -ex \
- && cd /usr/src/nginx-quic \
+ && cd /usr/src/nginx \
&& echo ./auto/configure \
# all dynamic modules need to be built with the same configure arguments as nginx
$(/usr/sbin/nginx -V 2>&1 | grep 'configure arguments:' | sed 's#.*arguments: ##') \
@@ -94,7 +55,6 @@ RUN set -ex \
--add-dynamic-module=/usr/src/njs/nginx \
# third-party dynamic modules
--add-dynamic-module=/usr/src/ngx_brotli \
- --add-dynamic-module=/usr/src/zstd-nginx-module \
--add-dynamic-module=/usr/src/nginx-module-vts \
--add-dynamic-module=/usr/src/ngx_http_geoip2_module \
--add-dynamic-module=/usr/src/ngx-fancyindex \
@@ -108,23 +68,51 @@ RUN set -ex \
# move new modules to /usr/lib/nginx/modules
&& find ./objs -name 'ngx*.so' | xargs -I{} mv {} /usr/lib/nginx/modules/
+# build njs command-line utility
+RUN set -ex \
+ && cd /usr/src/njs \
+ && ./configure \
+ && make njs -j$(nproc) \
+ && cp ./build/njs /usr/bin/njs \
+ && chmod +x /usr/bin/njs
+
+# download GeoIP2 databases
+RUN set -ex \
+ && mkdir -p /usr/share/GeoIP \
+ && curl -sSL -o /usr/share/GeoIP/GeoLite2-ASN.mmdb \
+ https://github.com/P3TERX/GeoLite.mmdb/releases/latest/download/GeoLite2-ASN.mmdb \
+ && curl -sSL -o /usr/share/GeoIP/GeoLite2-City.mmdb \
+ https://github.com/P3TERX/GeoLite.mmdb/releases/latest/download/GeoLite2-City.mmdb \
+ && curl -sSL -o /usr/share/GeoIP/GeoLite2-Country.mmdb \
+ https://github.com/P3TERX/GeoLite.mmdb/releases/latest/download/GeoLite2-Country.mmdb
+
+# ==================================================================================================== #
+FROM node AS njs-acme-builder
+
+WORKDIR /app
+COPY ./modules/njs-acme .
+
+RUN set -ex \
+ && npm install \
+ && npm run build
+
# ==================================================================================================== #
FROM nginx:${NGINX_VERSION}
# remove old modules
RUN rm -rf /usr/lib/nginx/modules
-# copy nginx binary and modules from builder
-COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx
+# copy build artifacts from builder stage
COPY --from=builder /usr/lib/nginx/modules /usr/lib/nginx/modules
-# copy libressl dynamic libraries from builder
-COPY --from=builder /usr/lib/libcrypto.so* /usr/lib/
-COPY --from=builder /usr/lib/libssl.so* /usr/lib/
+COPY --from=builder /usr/bin/njs /usr/bin/njs
+COPY --from=builder /usr/share/GeoIP /usr/share/GeoIP
+COPY --from=njs-acme-builder /app/dist/acme.js /usr/lib/nginx/njs_modules/acme.js
# install runtime dependencies
RUN set -ex \
&& apt-get update -y \
&& apt-get install -y --no-install-recommends \
+ libpcre3 \
libgd3 \
libgeoip1 \
libxslt1.1 \
diff --git a/README.md b/README.md
index e3b859c..23d2b91 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# NGINX docker image for HTTP/3 (QUIC) support
+# NGINX docker image with many useful modules
[![build][gha-badge]][gha-link]
[![dockerhub pulls][dockerhub-pull-badge]][dockerhub-tags]
@@ -7,67 +7,26 @@
[![license][license-badge]][license]
[![arch][arch-badge]][dockerhub-tags]
-[gha-badge]: https://github.com/nginx-quic/docker-nginx-quic/actions/workflows/ci.yml/badge.svg
-[gha-link]: https://github.com/nginx-quic/docker-nginx-quic/actions/workflows/ci.yml
-[dockerhub-tags]: https://hub.docker.com/r/zengxs/nginx-quic/tags
-[dockerhub-pull-badge]: https://img.shields.io/docker/pulls/zengxs/nginx-quic?logo=docker
-[dockerhub-size-badge]: https://img.shields.io/docker/image-size/zengxs/nginx-quic?logo=docker
-[dockerhub-version-badge]: https://img.shields.io/docker/v/zengxs/nginx-quic?logo=docker
-[license-badge]: https://img.shields.io/github/license/nginx-quic/nginx-quic
+[gha-badge]: https://github.com/zengxs/docker-nginx/actions/workflows/ci.yml/badge.svg
+[gha-link]: https://github.com/zengxs/docker-nginx/actions/workflows/ci.yml
+[dockerhub-tags]: https://hub.docker.com/r/zengxs/nginx/tags
+[dockerhub-pull-badge]: https://img.shields.io/docker/pulls/zengxs/nginx?logo=docker
+[dockerhub-size-badge]: https://img.shields.io/docker/image-size/zengxs/nginx?logo=docker
+[dockerhub-version-badge]: https://img.shields.io/docker/v/zengxs/nginx?logo=docker
+[license-badge]: https://img.shields.io/github/license/zengxs/docker-nginx
[license]: ./LICENSE
[arch-badge]: https://img.shields.io/badge/arch-x86__64%20%7C%20arm64-lightgrey
-[libressl]: https://www.libressl.org/
-[quictls]: https://github.com/quictls/openssl/
-[boringssl]: https://boringssl.googlesource.com/boringssl/
-Drop-in replacement for the official NGINX docker image, with HTTP/3 (QUIC) support.
+Drop-in replacement for the official nginx image with many useful modules.
-## What is this image?
+You can use it just like the official image without any changes, but you can enjoy many
+useful modules that are not included in the official image by adding some simple `load_module`
+directives in your NGINX configuration.
-NGINX now has support for HTTP/3 (QUIC), but the official docker image doesn't have it.
-this image is a drop-in replacement for the official image, with HTTP/3 (QUIC) support.
-
-This image is based on the official NGINX docker image and adds support for HTTP/3 (QUIC)
-using the [LibreSSL][libressl] library. The image use the same build configuration as the
-official image, and just update the NGINX binary to support HTTP/3.
-
-Also, the image adds some popular third-party modules, they are linked dynamically, that
-means there will be no overhead if you don't use them. But if you want to use them, you
-don't need to build your own image, just add some `load_module` directives in your NGINX
-configuration file.
-
-Other than that, the image is the same as the official one, so you can use it as a drop-in
-replacement for the official image.
-
-## Why LibreSSL?
-
-At this moment, NGINX can use three SSL implementations to support HTTP/3 (QUIC):
-[BoringSSL][boringssl], [QuicTLS][quictls] and [LibreSSL][libressl].
-
-BoringSSL is Google's fork of OpenSSL and it is used by Chromium and Google's other projects.
-It is not aims server-side use, and it documented:
-
-> 1. that is designed to meet Google's needs.
-> 2. it is not intended for general use.
-> 3. We don't recommend that third parties depend upon it.
-
-QuicTLS is a fork of OpenSSL enabled with QUIC support, but it's not ready for production.
-
-LibreSSL is a fork of OpenSSL, it is a security-focused, modern version of the TLS/crypto
-library. It is a drop-in replacement for OpenSSL, and it is used by many projects, such as
-OpenSSH, OpenBSD, macOS, etc.
-
-So I think LibreSSL is the best choice for this image.
-
-## How to pull the image?
-
-```sh
-# Pull the image from GitHub Container Registry
-docker pull ghcr.io/nginx-quic/nginx-quic
-
-# Or pull the image from Docker Hub
-docker pull zengxs/nginx-quic
-```
+> **NOTE**: This image is based on the official image debian variant, and all default
+> configurations are the same as the official image. So you must explicitly enable the
+> modules you want to use, otherwise this image will not be different from the official
+> image.
## How to use this image?
@@ -80,8 +39,8 @@ Change your docker-compose file like this:
version: '3.9'
services:
nginx:
-- image: nginx:1.23.3
-+ image: ghcr.io/nginx-quic/nginx-quic:1.23.3
+- image: nginx:1.25.2
++ image: zengxs/nginx:1.25.2
```
Or change your docker command like this:
@@ -93,45 +52,37 @@ Or change your docker command like this:
-v $PWD/conf.d:/etc/nginx/conf.d \
-v $PWD/certs:/etc/nginx/certs \
-p 80:80 -p 443:443 \
-- nginx:1.23.3
-+ ghcr.io/nginx-quic/nginx-quic:1.23.3
+- nginx:1.25.2
++ zengxs/nginx:1.25.2
```
-> **NOTE:**
->
-> The image is based on the official `debian` variant (default variant), so if you are
-> using the `alpine` variant before, may this image is not a drop-in replacement for you.
->
-> But if you are not doing anything special in your image, you can just replace the image
-> name, and it should work.
->
-> The `debian` variant is the default official variant, it not only has the best compatibility,
-> but also has the best performance. So I think it is the best choice for this image.
-
## Third-party modules
-| Module | Description | Dynamic module file name |
-| ------------------------------------------------------- | ---------------------------------------------- | --------------------------------------------------------------------- |
-| [ngx_brotli][mod-brotli] | Brotli compression module maintained by Google | ngx_http_brotli_filter_module.so
ngx_http_brotli_static_module.so |
-| [zstd-nginx-module][mod-zstd] | Zstandard compression module | ngx_http_zstd_filter_module.so
ngx_http_zstd_static_module.so |
-| [headers-more-nginx-module][mod-headers-more] | More set of headers for NGINX | ngx_http_headers_more_filter_module.so |
-| [nginx-module-vts][mod-vts] | Nginx virtual host traffic status module | ngx_http_vhost_traffic_status_module.so |
-| [ngx_http_geoip2_module][mod-geoip2] | GeoIP2 module for NGINX | ngx_http_geoip2_module.so
ngx_stream_geoip2_module.so |
-| [ngx-fancyindex][mod-fancyindex] | Fancy indexes module for NGINX | ngx_http_fancyindex_module.so |
-| [ngx_http_substitutions_filter_module][mod-subs-filter] | Substitutions filter module for NGINX | ngx_http_subs_filter_module.so |
+### Dynamic modules
+
+| Module | Description | Dynamic module file name |
+| ------------------------------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------------- |
+| [ngx_brotli][mod-brotli] | Brotli compression module maintained by Google | ngx_http_brotli_filter_module.so
ngx_http_brotli_static_module.so |
+| [headers-more-nginx-module][mod-headers-more] | More set of headers for NGINX | ngx_http_headers_more_filter_module.so |
+| [nginx-module-vts][mod-vts] | Nginx virtual host traffic status module | ngx_http_vhost_traffic_status_module.so |
+| [ngx_http_geoip2_module][mod-geoip2] | GeoIP2 module for NGINX (GeoLite2 database included[^geolite]) | ngx_http_geoip2_module.so
ngx_stream_geoip2_module.so |
+| [ngx-fancyindex][mod-fancyindex] | Fancy indexes module for NGINX | ngx_http_fancyindex_module.so |
+| [ngx_http_substitutions_filter_module][mod-subs-filter] | Substitutions filter module for NGINX | ngx_http_subs_filter_module.so |
[mod-brotli]: https://github.com/google/ngx_brotli
-[mod-zstd]: https://github.com/tokers/zstd-nginx-module
[mod-headers-more]: https://github.com/openresty/headers-more-nginx-module
[mod-vts]: https://github.com/vozlt/nginx-module-vts
[mod-geoip2]: https://github.com/leev/ngx_http_geoip2_module
[mod-fancyindex]: https://github.com/aperezdc/ngx-fancyindex
[mod-subs-filter]: https://github.com/yaoweibin/ngx_http_substitutions_filter_module
-Also you can ls the `/usr/lib/nginx/modules` directory to see all the available dynamic modules:
+[^geolite]: GeoLite2 database is located at `/usr/share/GeoIP/GeoLite2-{ASN,City,Country}.mmdb`.
+
+All dynamic modules are installed in `/usr/lib/nginx/modules` directory. You can use the
+following command to list them:
```sh
-docker run --rm -it ghcr.io/nginx-quic/nginx-quic ls -lh /usr/lib/nginx/modules/
+docker run --rm -it zengxs/nginx ls -lh /usr/lib/nginx/modules/
```
You can enable them by simply adding some `load_module` directives in your NGINX configuration:
@@ -141,6 +92,38 @@ load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
```
+### `njs` modules
+
+| Module | Description | JS module file name |
+| ------------------------ | --------------------- | ------------------- |
+| [njs-acme][mod-njs-acme] | ACME module for NGINX | `acme.js` |
+
+[mod-njs-acme]: https://github.com/nginx/njs-acme
+
+All `njs` modules are installed in `/usr/share/nginx/njs_modules` directory. You can use the
+following command to list them:
+
+```sh
+docker run --rm -it zengxs/nginx ls -lh /usr/share/nginx/njs_modules/
+```
+
+You must enable the `njs` module to use `njs` modules:
+
+```nginx
+# load dynamic modules
+load_module modules/ngx_http_js_module.so;
+load_module modules/ngx_stream_js_module.so;
+
+# set search path for njs
+js_path /usr/share/nginx/njs_modules;
+```
+
+Then you can import njs modules in your NGINX configuration:
+
+```nginx
+js_import acme from 'acme.js';
+```
+
## License
All submodules are licensed under their own licenses. Other files are licensed under the
diff --git a/libressl b/libressl
deleted file mode 160000
index aa1f9b1..0000000
--- a/libressl
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit aa1f9b11664ac41f304b638ec259d937fee6281e
diff --git a/modules/ngx_brotli b/modules/ngx_brotli
index 6e975bc..63ca02a 160000
--- a/modules/ngx_brotli
+++ b/modules/ngx_brotli
@@ -1 +1 @@
-Subproject commit 6e975bcb015f62e1f303054897783355e2a877dc
+Subproject commit 63ca02abdcf79c9e788d2eedcc388d2335902e52
diff --git a/modules/ngx_http_geoip2_module b/modules/ngx_http_geoip2_module
index cbaa354..a607a41 160000
--- a/modules/ngx_http_geoip2_module
+++ b/modules/ngx_http_geoip2_module
@@ -1 +1 @@
-Subproject commit cbaa35461c62a99d2577e6bae3273492502d8769
+Subproject commit a607a41a8115fecfc05b5c283c81532a3d605425
diff --git a/modules/njs b/modules/njs
index 9645655..5129f50 160000
--- a/modules/njs
+++ b/modules/njs
@@ -1 +1 @@
-Subproject commit 9645655a22d588cebb27bda9c455c8fac7b74ceb
+Subproject commit 5129f50040568b2e938ced0b10431b030a453170
diff --git a/modules/njs-acme b/modules/njs-acme
new file mode 160000
index 0000000..5936065
--- /dev/null
+++ b/modules/njs-acme
@@ -0,0 +1 @@
+Subproject commit 59360653ced6feb9c24523f193baa2da432237ff
diff --git a/modules/zstd-nginx-module b/modules/zstd-nginx-module
deleted file mode 160000
index 1e0fa0b..0000000
--- a/modules/zstd-nginx-module
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 1e0fa0bfb995e72f8f7e4c0153025c3306f1a5cc
diff --git a/nginx b/nginx
new file mode 160000
index 0000000..b489ba8
--- /dev/null
+++ b/nginx
@@ -0,0 +1 @@
+Subproject commit b489ba83e9be446923facfe1a2fe392be3095d1f
diff --git a/nginx-quic b/nginx-quic
deleted file mode 160000
index a1bb12e..0000000
--- a/nginx-quic
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit a1bb12e14ee86fdac2877c3a834b604f5bc522ae