1.尽量使用小型的基础镜像
Alpine Linux是一种基于musl libc和BusyBox的轻量级Linux发行版。它专注于安全、简单和高效,以最小化系统资源消耗和攻击面。Alpine Linux采用apk包管理器,使软件安装和更新变得简单和快速。它也可以作为容器镜像的基础操作系统,因为它的镜像非常小,这使得它适合于云原生应用和微服务架构
2.尽量移除不必要数据(文件 ,包<编译后将编译依赖包去除,保留运行时依赖>)
3.尽量减少镜像层数
4.可以采取 多阶段 构建镜像
5.如果可以实现为全静态项目,采用空(scratch)基础镜像构建
多阶段构建
# 第一阶段:构建nginx
FROM alpine:latest AS builder
# 更改apk源为阿里云源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 复制nginx源代码包
COPY nginx-1.22.0.tar.gz /tmp
# 安装构建依赖并编译nginx
RUN apk add --no-cache make gcc libgcc libc-dev zlib-dev pcre-dev openssl-dev && \
cd /tmp && \
tar -xf nginx-1.22.0.tar.gz && \
cd nginx-1.22.0 && \
./configure --prefix=/usr/local/nginx --with-http_ssl_module \
--with-http_auth_request_module --with-http_random_index_module && \
make -j2 && \
make install && \
# 清理构建依赖
apk del make gcc libc-dev zlib-dev pcre-dev openssl-dev && \
rm -rf /tmp/nginx-1.22.0 /tmp/nginx-1.22.0.tar.gz
# 第二阶段:运行nginx
FROM alpine:latest
# 复制编译好的nginx
COPY --from=builder /usr/local/nginx /usr/local/nginx
# 复制nginx配置文件和静态文件
COPY nginx.conf /usr/local/nginx/conf/nginx.conf
COPY xxl /usr/local/nginx/html
# 设置工作目录
WORKDIR /usr/local/nginx/html
# 启动nginx
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
用此Dockerfile构建的镜像,构建容器,容器会立即退出,查看log:
[root@bolog sinatra]# docker logs cfa4c08f96c3
Error loading shared library libpcre.so.1: No such file or directory (needed by /usr/local/nginx/sbin/nginx)
Error relocating /usr/local/nginx/sbin/nginx: pcre_exec: symbol not found
Error relocating /usr/local/nginx/sbin/nginx: pcre_config: symbol not found
Error relocating /usr/local/nginx/sbin/nginx: pcre_fullinfo: symbol not found
Error relocating /usr/local/nginx/sbin/nginx: pcre_compile: symbol not found
Error relocating /usr/local/nginx/sbin/nginx: pcre_study: symbol not found
Error relocating /usr/local/nginx/sbin/nginx: pcre_free_study: symbol not found
Error relocating /usr/local/nginx/sbin/nginx: pcre_free: symbol not found
Error relocating /usr/local/nginx/sbin/nginx: pcre_malloc: symbol not found
错误信息表明在运行nginx时找不到所需的共享库 libpcre.so.1
,这是因为在运行阶段的Alpine镜像中缺少 libpcre
库。虽然在构建阶段安装了相关的开发包,但在运行阶段没有安装这些库。
所以修改Dockersfile
# 第一阶段:构建nginx
FROM alpine:latest AS builder
# 更改apk源为阿里云源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 复制nginx源代码包
COPY nginx-1.22.0.tar.gz /tmp
# 安装构建依赖并编译nginx
RUN apk add --no-cache make gcc libgcc libc-dev zlib-dev pcre-dev openssl-dev && \
cd /tmp && \
tar -xf nginx-1.22.0.tar.gz && \
cd nginx-1.22.0 && \
./configure --prefix=/usr/local/nginx --with-http_ssl_module \
--with-http_auth_request_module --with-http_random_index_module && \
make -j2 && \
make install && \
# 清理构建依赖
apk del make gcc libc-dev zlib-dev pcre-dev openssl-dev && \
rm -rf /tmp/nginx-1.22.0 /tmp/nginx-1.22.0.tar.gz
# 第二阶段:运行nginx
FROM alpine:latest
# 更改apk源为阿里云源并安装运行时依赖
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add --no-cache pcre openssl zlib
# 复制编译好的nginx
COPY --from=builder /usr/local/nginx /usr/local/nginx
# 复制nginx配置文件和静态文件
COPY nginx.conf /usr/local/nginx/conf/nginx.conf
COPY xxl /usr/local/nginx/html
# 设置工作目录
WORKDIR /usr/local/nginx/html
# 启动nginx
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@bolog sinatra]# docker build --no-cache -t xxl-apline-src:v3 .
[root@bolog sinatra]# docker run -dt --name game3 -p82:80 xxl-apline-src:v3
997ba78618b9896dff28fda4b7b3ad71b4ef726b5596c1767d3f8a7bddc3e057
[root@bolog sinatra]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
997ba78618b9 xxl-apline-src:v3 "/usr/local/nginx/sb…" 3 seconds ago Up 2 seconds 0.0.0.0:82->80/tcp, :::82->80/tcp game3
bea8055b95df xxl-alpine-bin:v1 "/usr/local/nginx/sb…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp, :::80->80/tcp game
结果对比
[root@bolog sinatra]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xxl-apline-src v3 8168b45956e6 9 minutes ago 16.8MB
xxl-apline-src v2 bf8194f9f50d 2 hours ago 15.6MB
xxl-alpine-src v1 5d8f65081b64 3 hours ago 176MB
由此可见,使用多阶段构建可以极大的节约空间
为什么能减少这么多空间
构建阶段和运行阶段分离:
在多阶段构建中,构建阶段使用了包含开发工具和库的基础镜像,这些工具和库只在编译和构建nginx时需要。
运行阶段使用了一个干净的Alpine镜像,只包含运行nginx所需的最小文件和依赖。这意味着不需要在最终镜像中包含编译工具和中间文件。
减少了不必要的依赖:
在构建阶段,安装了编译nginx所需的所有依赖(如
make
、gcc
、libc-dev
、zlib-dev
、pcre-dev
、openssl-dev
),这些依赖在编译完成后被删除。运行阶段只安装了nginx运行时所需的最小依赖(如
pcre
、openssl
、zlib
),大大减少了最终镜像中不必要的文件。
清理构建文件:
在构建完成后,删除了构建过程中生成的临时文件和缓存(如
/tmp/nginx-1.22.0
和/tmp/nginx-1.22.0.tar.gz
),确保最终镜像干净整洁,避免了冗余数据的增加。
压缩的层次:
使用多阶段构建时,只有构建阶段生成的有效文件(如nginx的可执行文件和配置文件)被复制到最终镜像中。每个阶段的镜像层数被有效地压缩,减少了不必要的层次。