Docker Nginx 官方包源启用 Brotli 压缩算法

528次阅读
没有评论

共计 4875 个字符,预计需要花费 13 分钟才能阅读完成。

Nginx 官方镜像只包含了官方版本所支持的模块,第三方模块并未包含其中,需要自己构建Docker镜像,只是网上很多教程都采用了自己编写的 Dokcerfile 拉取的是 Github 存储库最原始的代码进行编译感觉不太稳定。Nginx Docker 官方仓库提供了 pkg-oss 包源添加第三方模块的方法,这个包源是 Nginx 官方维护的有一定的稳定性保证。

构建Nginx自定义第三方模块镜像

Github 官方教程,在教程官方列出了可以直接从官方维护的 pkg-oss 拉取的第三方模块如下:

/pkg-oss $ LC_ALL=C make -C debian list-all-modules
make: Entering directory '/pkg-oss/debian'
auth-spnego             1.1.1-1
brotli                  1.0.0-1
encrypted-session       0.09-1
fips-check              0.1-1
geoip                   1.25.1-1
geoip2                  3.4-1
headers-more            0.34-1
image-filter            1.25.1-1
lua                     0.10.25-1
modsecurity             1.0.3-3
ndk                     0.3.2-1
njs                     0.8.0-1
opentracing             0.29.0-1
passenger               6.0.18-1
perl                    1.25.1-1
rtmp                    1.2.2-1
set-misc                0.33-1
subs-filter             0.6.4-1
xslt                    1.25.1-1
make: Leaving directory '/pkg-oss/debian'

官方并未发布有关Docker镜像,需要自行进行构建编译,在教程中官方也提供了相关 Dockerfile 并提供了基于 alpine 和 debian 两个版本,下面是我根据官方 alpine 版本的 Dockerfile 添加代码 RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories 替换清华的镜像源提高构建速度。


ARG NGINX_FROM_IMAGE=nginx:mainline-alpine
FROM ${NGINX_FROM_IMAGE} as builder

ARG ENABLED_MODULES

RUN set -ex \
    && if [ "$ENABLED_MODULES" = "" ]; then \
        echo "No additional modules enabled, exiting"; \
        exit 1; \
    fi

# COPY ./ /modules/

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
RUN set -ex \
    && apk update \
    && apk add linux-headers openssl-dev pcre2-dev zlib-dev openssl abuild \
               musl-dev libxslt libxml2-utils make mercurial gcc unzip git \
               xz g++ coreutils \
    # allow abuild as a root user \
    && printf "#!/bin/sh\\nSETFATTR=true /usr/bin/abuild -F \"\$@\"\\n" > /usr/local/bin/abuild \
    && chmod +x /usr/local/bin/abuild \
    && hg clone -r ${NGINX_VERSION}-${PKG_RELEASE} https://hg.nginx.org/pkg-oss/ \
    && cd pkg-oss \
    && mkdir /tmp/packages \
    && for module in $ENABLED_MODULES; do \
        echo "Building $module for nginx-$NGINX_VERSION"; \
        if [ -d /modules/$module ]; then \
            echo "Building $module from user-supplied sources"; \
            # check if module sources file is there and not empty
            if [ ! -s /modules/$module/source ]; then \
                echo "No source file for $module in modules/$module/source, exiting"; \
                exit 1; \
            fi; \
            # some modules require build dependencies
            if [ -f /modules/$module/build-deps ]; then \
                echo "Installing $module build dependencies"; \
                apk update && apk add $(cat /modules/$module/build-deps | xargs); \
            fi; \
            # if a module has a build dependency that is not in a distro, provide a
            # shell script to fetch/build/install those
            # note that shared libraries produced as a result of this script will
            # not be copied from the builder image to the main one so build static
            if [ -x /modules/$module/prebuild ]; then \
                echo "Running prebuild script for $module"; \
                /modules/$module/prebuild; \
            fi; \
            /pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); \
            BUILT_MODULES="$BUILT_MODULES $(echo $module | tr '[A-Z]' '[a-z]' | tr -d '[/_\-\.\t ]')"; \
        elif make -C /pkg-oss/alpine list | grep -E "^$module\s+\d+" > /dev/null; then \
            echo "Building $module from pkg-oss sources"; \
            cd /pkg-oss/alpine; \
            make abuild-module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \
            apk add $(. ./abuild-module-$module/APKBUILD; echo $makedepends;); \
            make module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \
            find ~/packages -type f -name "*.apk" -exec mv -v {} /tmp/packages/ \;; \
            BUILT_MODULES="$BUILT_MODULES $module"; \
        else \
            echo "Don't know how to build $module module, exiting"; \
            exit 1; \
        fi; \
    done \
    && echo "BUILT_MODULES=\"$BUILT_MODULES\"" > /tmp/packages/modules.env

FROM ${NGINX_FROM_IMAGE}
COPY --from=builder /tmp/packages /tmp/packages
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
RUN set -ex \
    && . /tmp/packages/modules.env \
    && for module in $BUILT_MODULES; do \
           apk add --no-cache --allow-untrusted /tmp/packages/nginx-module-${module}-${NGINX_VERSION}*.apk; \
       done \
    && rm -rf /tmp/packages

上面的 Dockerfile 读取docker 构建参数 ENABLED_MODULES 在上面的 pkg-oss 列表中的地方模块都可以在这个参数中指定,如 ENABLED_MODULES="ndk lua" 的形式,这里我这只需添加 brotli 这个第三方模块,可以使用两种构建命令,一种是在 Dockerfile 目录下执行 docker build 命令如下:

docker build --build-arg ENABLED_MODULES="brotli" -t my-nginx-with-lua .

其中-t 后面可以自己指定构建 Tag。还有一种方法是在 Docker Compose 中进行构建,这种方法更方便管理。运行参数暂时不考虑,添加如下 docker-compose.yaml 文件:

version: "3.3"

services:

  nginx:
    build:
      context: ./
      args:
        ENABLED_MODULES: brotli
    image: my-nginx-with-lua

其中context 可以根据你的 docker-compose.yaml 和 Dockerfile 文件的相对路径自行修改。 ENABLED_MODULES 指定要编译的第三方模块,可以添加多个第三方模块,修改为 ENABLED_MODULES: "ndk lua" 这种形式就可以了。然后在目录下执行以下命令。

docker compose build nginx

示例中会构建包含 brotli 第三方插件的 docker nginx 镜像,可以在本地直接使用可以使用 docker push my-nginx-with-lua 其中my-nginx-with-lua 为你自定义的tag名称或者 image名称推送到阿里云镜像仓库中分发给使用。下面演示在本地使用brotli 第三方插件。

Nginx中配置使用 brotli

使用第三方模块需要在配置文件中导入,以下是 nginx 开启 brotli 的简化配置。


# 载入 brotli 模块
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

worker_processes     auto;
events {
    worker_connections  1024;
}
http {
    # 在http节开启 brotli 压缩
    brotli_static       on;
    brotli              on;
    brotli_types        *;
    brotli_comp_level   6;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    sendfile        on;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

}

总结

Nginx 官方 Docker 仓库 提供这种配置方法可以安装多个第三方插件,并且插件的包源是官方维护的一定程度上保证了其稳定性。可以在开发主机上构建后再编译发布到镜像仓库中,自己维护一个版本使用。也可以随时跟上官方更新最新的 Nginx 版本。

正文完
 
太阳
版权声明:本站原创文章,由 太阳 2023-11-13发表,共计4875字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)