注:因考虑到不同测试机器的环境有差异,可能造成编译后仍有动态库依赖的问题,故选择在alpine的Docker基础镜像环境下编译,请先自行安装Docker
脚本涵盖Nginx日常大部分所需模块,默认已集成GeoIP2库,如不需要可自行去除(5-6行)
最终效果图如下,实现Nginx无动态依赖集成一体的静态编译
1.创建静态编译Nginx的Dockerfile文件
Dockerfile适用于任何版本的Nginx,包括Mainline和Stable的最新版本
Dockerfile内容如下:
FROM alpine AS build
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && apk --update add gcc g++ make wget file openssl-dev openssl-libs-static pcre2-dev zlib-dev zlib-static linux-headers && \
NGINX_VERSION=nginx-1.24.0 && \
NGINX_PATH=/usr/local/nginx && \
wget https://ghproxy.com/https://github.com/leev/ngx_http_geoip2_module/archive/refs/tags/3.4.tar.gz && tar -xf 3.4.tar.gz && \
wget https://ghproxy.com/https://github.com/maxmind/libmaxminddb/releases/download/1.7.1/libmaxminddb-1.7.1.tar.gz && tar -xf libmaxminddb-1.7.1.tar.gz && cd libmaxminddb-1.7.1 && ./configure && make -j 8 && make install && cd .. && \
wget https://nginx.org/download/${NGINX_VERSION}.tar.gz && tar -xf ${NGINX_VERSION}.tar.gz && cd ${NGINX_VERSION} && \
./configure \
--add-module=../ngx_http_geoip2_module-3.4 \
--http-client-body-temp-path=/tmp/client-body \
--http-fastcgi-temp-path=/tmp/fastcgi-temp \
--http-proxy-temp-path=/tmp/proxy-temp \
--http-scgi-temp-path=/tmp/scgi-temp \
--http-uwsgi-temp-path=/tmp/uwsgi-temp \
--prefix=${NGINX_PATH} \
--with-compat \
--with-file-aio \
--with-threads \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_v2_module \
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-cc-opt='-static -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC -fexceptions --param=ssp-buffer-size=4 -m64 -mtune=generic' \
--with-ld-opt='-static -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -Wl,--as-needed,-O1,--sort-common' && \
make -j 8 && \
make install
FROM alpine
COPY --from=build ["/usr/local/nginx", "/usr/local/nginx"]
参数说明:
第3行中NGINX_VERSION为Nginx版本,默认为1.24.0
,有需要可自行更改
第4行中NGINX_PATH为Nginx安装路径,默认为/usr/local/nginx
,有需要可自行更改
Nginx名称和版本号修改说明(用于修改头部名称和版本号,默认为nginx/1.24.0
,有需要可自行更改):
# 源代码目录 src/core/nginx.h 文件:
#define nginx_version 1024000
#define NGINX_VERSION "1.24.0"
#define NGINX_VER "nginx/" NGINX_VERSION
# 源代码目录 src/http/ngx_http_header_filter_module.c 文件:
static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
# 源代码目录 src/http/ngx_http_special_response.c 文件:
"<hr><center>nginx</center>" CRLF
2.构建镜像
docker build -f Dockerfile -t nginx-static:1.24.0 .
-f参数后为Dockerfile的文件名,-t参数后为构建后的镜像标签,如有不同请自行修改
3.启动容器
等待构建成功后即可启动容器
docker run -id --name nginx-static nginx-static:1.24.0
4.拷贝容器Nginx文件夹到本地
docker cp nginx-static:/usr/local/nginx /usr/local
若前面更改过Nginx的安装路径,请自行修改,默认为/usr/local/nginx
经多次测试,Nginx的配置路径无法做成相对路径,会有一系列报错,故后期若需要更新Nginx版本及配置路径,请重新构建
OpenRestry的静态编译也尝试过,没果,主要是lua的静态编译问题,如有大佬能实现请赐教
5.删除容器
docker rm -f nginx-static
附上两个编译参数的参数解释(参数从Nginx默认的官方debian和alpine镜像中提取整合):
--with-cc-opt='-static -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC -fexceptions --param=ssp-buffer-size=4 -m64 -mtune=generic'
--with-cc-opt
: 这是用于设置编译器选项的参数。-static
: 这是一个编译选项,它告诉编译器在生成可执行文件时使用静态链接,以避免依赖外部共享库。-O2
: 这是优化级别的选项,表示使用级别2的编译优化。级别2是中级优化,通常会在代码大小和性能之间取得平衡。-fstack-protector-strong
: 这是一种堆栈保护机制,用于检测并防止缓冲区溢出攻击。-Wformat
: 这个选项启用了在格式化字符串中的安全检查,以避免格式化字符串漏洞。-Werror=format-security
: 这个选项会将格式化字符串安全问题视为错误。-Wp,-D_FORTIFY_SOURCE=2
: 这个选项定义了_FORTIFY_SOURCE宏,它提供了一些针对缓冲区溢出的额外保护。-fPIC
: 这是生成位置无关代码(Position-Independent Code)的选项,用于在动态链接库中使用。-fexceptions
: 这个选项启用了异常处理支持。--param=ssp-buffer-size=4
: 这个选项设置堆栈保护缓冲区的大小为4字节。-m64
: 这是生成64位代码的选项。-mtune=generic
: 这个选项告诉编译器将生成的代码调优为适合通用处理器。
--with-ld-opt='-static -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie -Wl,--as-needed,-O1,--sort-common'
--with-ld-opt
: 这是用于设置链接器选项的参数。-static
: 同上面的解释,这告诉链接器在链接时使用静态链接。-Wl,-z,relro
: 这是链接器选项,启用了"Partial Relocation Read-Only"(RELRO)保护,用于增加二进制文件的安全性。-Wl,-z,now
: 这个选项要求链接器在加载时立即解析所有符号,以增加代码的安全性。-Wl,--as-needed
: 这个选项会在链接时去掉不需要的依赖项,以减少生成的可执行文件的依赖。-pie
: 这是一个生成位置独立可执行文件(Position-Independent Executable)的选项,与代码的位置无关。-Wl,--as-needed,-O1,--sort-common
: 这个选项在链接时进行额外的优化,包括去除不需要的依赖项和排序公共符号。