前端 Docker 镜像体积优化(node+nginx/node+多阶段构建)

4,497 阅读3分钟

前言

最近写一个需求react项目前端构建之后的体积过大,以及构建速度慢的问题,写完需求之后,做一个总结。

构建速度慢

构建速度慢主要的原因,是安装node_modules依赖包慢,而且需要连网。

构建速度慢解决方法

由于node_modulesz在项目中变化不会很频繁,所以将安装node_modules依赖包单独提出来构建,作为一个基础镜像,这样如果项目中的代码变化,依赖不变化,这个安装依赖的过程就不会执行,而是从何FROM命令引入基础镜像,将node_modules文件复制到react项目中,再进行代码构建,从而减少构建时间。

基础镜像文件内容

FROM node

RUN set -x \
    && mkdir -p /web-tmp \
    && cd /web-tmp \
    && git clone -b develop git地址 . \
    && mkdir -p /test/web \
    && mv /web-tmp/web/package.json /test/web/ \
    && mv /web-tmp/web/package-lock.json /test/web/ \
    && rm -rf /web-tmp \
    && cd /test/web/ \    
    && npm install  --registry=https://registry.npm.taobao.org \
    && npm install express commander -g --registry=https://registry.npm.taobao.org

项目中镜像文件内容

COPY ./web/ /test/web/
RUN true
COPY ./web/.[^.]* /test/web/
RUN true
COPY ./nginx.conf /test/web/nginx.conf

RUN set -x \
    && cd /test/web/ \
    && npm run build
# nginx 镜像
FROM  docker.registry.test:5000/library/nginx:1.19.6-alpine

COPY --from=builder /test/web/nginx.conf /test/nginx/nginx.conf
RUN true
COPY --from=builder /test/web/build /test/web/

# 启动静态文件
CMD ["nginx", "-c", "/test/nginx/nginx.conf"]

EXPOSE 5602

构架体积过大原因

  • 主要的安装的node_modules依赖包没有删除
  • 项目的源代码没有删除 注:react项目中只有构建好的build文件,以及启动build文件是有用的,其余的文件都为无用文件,需要将其删除。

解决体积过大原因

  • 删除node_modules

    1. dockerfile中每一个大写的指令代码一层,如COPY,RUN,FROM...等等,层级越多,体积越大,所以在编写dockerfile时,应避免写多个RUN 指令,使用&&代替。 dockerfile 在同一层中删除文件,才会真正的删除,从而减少体积,如果在下面的层级中删除上面层级中的node_modules是无用的,不会减少文件的体积。每当代码变化就会触发构建,在同一层级中安装依赖并且构建代码,之后删除无用代码,会减小代码体积,但是构架时间会加长,很慢,不推荐此方法。
    2. 采用多阶段构建,第一阶段是:按照上面构建基础镜像的方法,将基础镜像构建完成,然后在项目中的dockerfile进入基础镜像,复制node_modules,执行npm run build,第二阶段是:将第一阶段构建好的build文件夹复制到第二阶段文件中,使用nginx启动build文件。(dockerfile 的多阶段构建是在上一阶段的构建的文件,不会保留到最后构建好的文件中,只保留最后一个阶段构建好的文件)通过此 方法来去掉node_modules文件,减少构建体积。
# node_modules 基础镜像 第一阶段
FROM docker.registry.test:5000/library/test-web-new-baseimage AS builder 

COPY ./web/ /test/web/
RUN true
COPY ./web/.[^.]* /test/web/
RUN true
COPY ./nginx.conf /test/web/nginx.conf

RUN set -x \
    && cd /test/web/ \
    && npm run build
# nginx 镜像 第二阶段
FROM  docker.registry.test:5000/library/nginx:1.19.6-alpine

COPY --from=builder /test/web/nginx.conf /test/nginx/nginx.conf
RUN true
COPY --from=builder /test/web/build /test/web/

# 启动静态文件
CMD ["nginx", "-c", "/test/nginx/nginx.conf"]

EXPOSE 5602

优化前文件大小1.9G,优化后大小30多M

nginx 文件配置

worker_processes  1;

pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    sendfile        on;

    keepalive_timeout  65;

    server {
      listen [::]:5602;
      listen  5602;
      server_name localhost;
      location / {
          #静态文件访问地址(只需要修改这个)
           root /test/web/; 
           index index.html index.htm;
           try_files $uri $uri/ /index.html = 404;
      }

    }

}

#让其持续输出
daemon off; 

总结

亲测有效,有疑问请留言。