为什么需要定制化编译

定制化编译和安装Nginx可以满足一些特定的使用场景和需求,包括但不限于以下几个方面:

  1. 模块选择:Nginx具有丰富的模块系统,可以通过定制化编译来选择需要的模块,并根据实际需求启用或禁用某些模块。例如,可以选择启用HTTP SSL模块、HTTP Gzip静态压缩模块、HTTP Cache模块、HTTP Rewrite模块等。这样可以根据具体的业务需求来配置Nginx,减少资源占用,提高性能和安全性。

  2. 功能扩展:通过自定义编译选项,可以将第三方模块或自己开发的模块集成到Nginx中,以满足特定的功能需求。这些模块可以实现各种定制化的功能,如访问控制、身份认证、日志处理、反向代理、负载均衡、缓存处理等。通过编译和安装自定义模块,可以将Nginx打造成适用于特定业务场景的高性能服务器。

  3. 最小化安装:定制化编译可以帮助最小化Nginx的安装。可以根据实际需求选择需要的功能和模块,以及相关依赖项,从而减少安装包的大小和系统资源的占用。这对于部署在资源受限的环境中,或者需要精简系统镜像的场景非常有用。

  4. 性能优化:通过定制化编译,可以针对具体硬件和操作系统环境进行优化,以提高Nginx的性能和效率。可以选择适当的编译选项、启用优化参数,并根据硬件架构设置相关优化,如使用特定的CPU指令集、启用TCP优化等。这样可以最大程度地发挥服务器的性能潜力,提高请求处理能力和并发性能。

  5. 安全性增强:通过定制化编译,可以启用或禁用特定的安全模块,加强Nginx的安全性。例如,启用HTTP SSL模块可以实现HTTPS通信加密;启用HTTP Security Headers模块可以添加安全相关的HTTP响应头;启用HTTP Firewall模块可以进行Web应用程序防火墙的功能等。通过编译和安装选择的安全模块,可以增强Nginx的安全性和防护能力。

总之,定制化编译Nginx可以根据具体需求选择模块、功能、性能优化和安全增强等选项,从而将Nginx打造成适应特定使用场景和业务需求。

定制化编译一般的流程

要进行Nginx的定制化编译和安装,可以按照以下步骤进行操作:

  1. 获取源代码:首先,从Nginx官方网站(https://nginx.org/)下载所需版本的源代码包,或者从GitHub仓库(https://github.com/nginx/nginx)获取最新的源代码。

  2. 解压源代码包:将下载的源代码包解压到合适的目录中。

  3. 安装依赖:根据系统的要求,安装构建Nginx所需的依赖项,如GCC编译器、PCRE库、OpenSSL库等。具体的依赖项可能因操作系统而异,可以参考Nginx官方的编译指南或相关文档。

  4. 配置编译选项:进入解压后的Nginx源代码目录,并运行configure脚本来配置编译选项。可以根据需要添加自定义的选项,如指定安装路径、启用或禁用模块等。以下是一个示例的配置命令:

    ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_gzip_static_module
    

    上述命令将指定安装路径为/usr/local/nginx,并启用了HTTP SSL模块和HTTP Gzip静态压缩模块。

  5. 编译和安装:运行make命令来编译Nginx,然后运行make install命令将编译后的二进制文件和相关文件安装到指定路径中。示例命令如下:

    make
    make install
    

    执行完这两个命令后,Nginx将被编译并安装到指定的安装路径。

  6. 配置和启动Nginx:根据实际需求,编辑Nginx的配置文件(通常位于安装路径的conf目录下),配置服务器块、监听端口、代理规则等。完成配置后,运行Nginx的可执行文件启动Nginx服务。示例命令如下:

    /usr/local/nginx/sbin/nginx
    

    如果一切顺利,Nginx将会启动并开始监听配置的端口。

请注意,上述步骤仅为一般的流程示例,具体的编译和安装过程可能因操作系统、版本和需求而有所差异。在进行定制化编译和安装时,建议参考Nginx官方的文档、编译指南或相关的社区资源,以获得更详细和准确的指导。

实战:使用docker定制化编译Nginx

参考文档:https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source

第一步:构建基础镜像

docker build -t nginx-base:v1 -f Dockerfile.base .
# Dockerfile.base
FROM nginx:mainline-alpine as builder
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN set -ex \
    && apk add \
        ca-certificates \
        tzdata \
        linux-headers \
        openssl \
        openssl-dev \
        pcre-dev \
        zlib-dev \
        abuild \
        musl-dev \
        libxslt \
        libxml2-utils \
        make \
        mercurial \
        gcc \
        git \
        g++ \
    # 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

第二步:构建nginx镜像

docker build -t demo:v1 -f Dockerfile .
FROM nginx-base:v1 as builder
RUN set -ex \ 
    && wget -O luajit-2.1.tar.gz https://github.com/openresty/luajit2/archive/refs/tags/v2.1-20210510.tar.gz \
    && tar -zxf luajit-2.1.tar.gz \
    && cd luajit2-2.1-20210510 \
    && make install PREFIX=/usr/local/luajit \
    && cd - \
    && export LUAJIT_LIB=/usr/local/luajit/lib \
    && export LUAJIT_INC=/usr/local/luajit/include/luajit-2.1 \
    && wget -O devel-v0.3.1.tar.gz  https://github.com/vision5/ngx_devel_kit/archive/refs/tags/v0.3.1.tar.gz \
    && tar -zxf devel-v0.3.1.tar.gz -C /usr/local \
    && wget https://github.com/openresty/lua-nginx-module/archive/refs/tags/v0.10.14.tar.gz \
    && tar -zxf v0.10.14.tar.gz -C /usr/local \ 
    && wget https://nginx.org/download/nginx-1.19.0.tar.gz \
    && tar -zxf nginx-1.19.0.tar.gz \
    && cd nginx-1.19.0 \
    && ./configure \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --conf-path=/etc/nginx/nginx.conf  \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock \
    --with-pcre \
    --with-http_ssl_module \
    --with-http_gzip_static_module \
    --with-stream \
    --with-http_addition_module \
    --with-http_realip_module \
    --with-http_auth_request_module \
    --with-http_realip_module \
    --with-mail \
    --with-mail_ssl_module \
    --with-ld-opt="-Wl,-rpath,/usr/local/luajit/lib" \
    --add-module=/usr/local/ngx_devel_kit-0.3.1 \
    --add-module=/usr/local/lua-nginx-module-0.10.14 \
    && make -j2 \
    && make install
FROM nginx:alpine
COPY --from=builder /etc/nginx /etc/nginx
COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx
COPY --from=builder /usr/local/luajit /usr/local/luajit
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN set -ex \
    && apk add \
    ca-certificates \
    gcc

测试

配置nginx

初始化:

mkdir -p conf/conf.d
mkdir lua
touch conf/conf.d/default.conf
touch conf/nginx.conf
touch lua/mydata.lua

mydata.lua内容如下:

 -- mydata.lua
 local _M = {}

 local data = {
     dog = 3,
     cat = 4,
     pig = 5,
 }

 function _M.get_age(name)
     return data[name]
 end

 return _M

nginx通用配置文件如下:

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"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    #tcp_nopush     on;

    keepalive_timeout 65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

    # lua文件加载路径
    lua_package_path '/etc/nginx/lua/default/?.lua;;';
}

server配置文件如下:

# /etc/conf.d/default.conf
server {
    listen 80;
    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
    location /hello {
        default_type 'text/plain';
        return 200 'hello echo!';
    }

    location /hello_lua {
        default_type 'text/plain';
        content_by_lua 'ngx.say("hello, lua!")';
    }

    location /lua {
        default_type 'text/plain';
        content_by_lua_block {
            local mydata = require "mydata"
            ngx.say(mydata.get_age("dog"))
        }
    }
}

启动测试Demo

docker run \
    --name nginx \
    -p 80:80 \
    -d \
    -v ${PWD}/conf/nginx.conf:/etc/nginx/nginx.conf \
    -v ${PWD}/conf/conf.d:/etc/nginx/conf.d \
    -v ${PWD}/logs:/etc/nginx/logs \
    -v ${PWD}/lua:/etc/nginx/lua/default \
    demo:v1

测试:

curl http://localhost/hello
curl http://localhost/hello_lua

参考链接