Docker Alpine 构建最小化 Nginx 镜像

docker 的好处不多说,我喜欢 docker 的原因是因为它不破坏本地环境,不需要每次都手动部署应用环境,只需要一条命令就能构建我想要的应用环境,而且可以跨平台运行,yyds。

准备好源码包存放在同一个目录,源码包的下载地址在 Dockerfile 文件里。

➜  nginx-docker ls
Dockerfile           build.sh             nginx-1.24.0.tar.gz  openssl-3.0.7.tar.gz pcre-8.45.tar.gz     zlib-1.3.1.tar.gz
➜  nginx-docker

Dockerfile 文件内容,nginx 采用源码静态编译,静态编译的好处是不依赖系统库。这样编译好的 nginx 就可以复制到其他容器运行,一次编译到处运行。

FROM alpine as base

ARG NGINX_VERSION=1.24.0
ARG OPENSSL_VERSION=3.0.7
ARG ZLIB_VERSION=1.3.1
ARG PCRE_VERSION=8.45

# http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
ADD nginx-${NGINX_VERSION}.tar.gz /

# https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz
ADD openssl-${OPENSSL_VERSION}.tar.gz /

# https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz  # 可能只有最新版
ADD zlib-${ZLIB_VERSION}.tar.gz /

# https://sourceforge.net/projects/pcre/files/pcre/${PCRE_VERSION}/pcre-${PCRE_VERSION}.tar.gz
ADD pcre-${PCRE_VERSION}.tar.gz /

RUN sed -i 's@dl-cdn.alpinelinux.org@mirrors.aliyun.com@' /etc/apk/repositories && \
apk update && \
apk add --no-cache --virtual .build-deps gcc g++ make file perl linux-headers && \
cd /nginx-${NGINX_VERSION} && \
./configure --prefix=/app/nginx \
--with-cc-opt='-static -static-libgcc' \
--with-ld-opt='-static' \
--sbin-path=/sbin/nginx \
--pid-path=/run/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/dev/stderr \
--http-log-path=/dev/stdout \
--with-compat \
--with-threads \
--with-file-aio \
--with-openssl=/openssl-${OPENSSL_VERSION} \
--with-zlib=/zlib-${ZLIB_VERSION} \
--with-pcre=/pcre-${PCRE_VERSION} \
--with-pcre \
--with-pcre-jit \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-http_auth_request_module \
--with-http_addition_module \
--with-http_sub_module \
--with-stream  && \
make && make install

FROM alpine

COPY --from=base /app/nginx /app/nginx
COPY --from=base /sbin/nginx /sbin/nginx
COPY --from=base /etc/nginx /etc/nginx

EXPOSE 80
ENTRYPOINT ["nginx", "-g", "daemon off;"]

开始构建 nginx 镜像,查看 nginx 镜像只有 18MB 左右。

$ docker build -t nginx:1.24.0 .

启动 nginx 容器,通过 ldd 命令查看/sbin/nginx 是没有关联到任何系统库的。

$ docker run -d --rm --name test-nginx -p 9000:80 nginx:1.24.0
$ docker exec -it test-nginx sh
/ # 
/ # ldd /sbin/nginx 
/lib/ld-musl-x86_64.so.1: /sbin/nginx: Not a valid dynamic program
/ # 
/ # exit
$