• 如何将 Docker 镜像大小从 1.43 GB 减少到 22.4 MB


     如果你正在从事 Web 开发,那么你可能已经了解过容器化的概念以及它的优点。

    但是,当使用 Docker 时,镜像大小是一个很大的问题。仅仅是从 create-react-app 中得到的样板项目就通常超过 1.43 GB。

    今天我们将会容器化一个 ReactJS 应用程序,并学习一些关于如何减小镜像大小以及同时提高性能的技巧。

    这些技巧将会展示给 ReactJS,但它同样适用于任何 NodeJS 应用程序。

    步骤1:创建您的项目

    把你的终端打开,输入以下命令:

    npx create-react-app docker-image-test

    然后create-react-app将为您提供基本的 React 应用程序。

    之后,进入根目录并运行项目。

    cd docker-image-testyarn installyarn start

    然后转到http://localhost:3000查看您的应用程序是否已启动并正在运行。

    步骤2:构建您的第一个图像

    在项目的根目录中,创建一个名为Dockerfile的文件并将以下代码粘贴到其中。

    1. FROM node:12
    2. WORKDIR /app
    3. COPY package.json ./
    4. RUN yarn install
    5. COPY . .
    6. EXPOSE 3000
    7. CMD ["yarn", "start"]

    请注意,我们正在从 docker hub 获取基本映像 node:12,安装依赖项并运行基本命令。(这里不深入docker命令的细节)

    现在从您的终端,为您的容器构建图像。

    docker build -t docker-image-test .

    Docker 将构建您的映像。完成后,您可以使用此命令查看您的图像。

    docker images

    列表顶部是我们新创建的图像,在最右侧,我们可以看到图像的大小。现在是1.43GB 。

    我们可以使用以下命令运行图像

    docker run --rm -it -p 3000:3000/tcp docker-image-test:latest

    您可以转到浏览器并刷新页面以验证它是否仍在运行。

    步骤3:更改基础图像

    在之前的配置中,我们使用node:12作为基础镜像。但传统上,节点图像是基于Ubuntu的,这对于我们简单的React应用程序来说是不必要的沉重。

    从 DockerHub(官方 docker image registry)可以看出,基于 Alpine 的镜像比基于 Ubuntu 的镜像要小得多,而且它们只打包了最小的依赖。

    这些基本图像的大小比较如下所示。

     现在我们将使用node:12-alpine作为我们的基础镜像,看看会发生什么。

    1. FROM node:12-alpine
    2. WORKDIR /app
    3. COPY package.json ./
    4. RUN yarn install
    5. COPY . .
    6. EXPOSE 3000
    7. CMD ["yarn", "start"]

    然后我们像以前一样构建图像并查看大小。

     哇!我们的图像大小只减少到580MB。这是一个很大的进步。但我们能做得更好吗?

    步骤4:多阶段构建

    在我们之前的配置中,我们将所有源代码复制到工作目录中。

    但这是不必要的,因为我们只需要构建文件夹来为我们的网站提供服务。所以现在,我们将使用多阶段构建的概念来减少最终图像中不必要的代码和依赖项。

    配置看起来像这样。

    1. # STAGE 1
    2. FROM node:12-alpine AS build
    3. WORKDIR /app
    4. COPY package.json ./
    5. RUN yarn install
    6. COPY . /app
    7. RUN yarn build
    8. # STAGE 2
    9. FROM node:12-alpine
    10. WORKDIR /app
    11. RUN npm install -g webserver.local
    12. COPY --from=build /app/build ./build
    13. EXPOSE 3000
    14. CMD webserver.local -d ./build

    在第一阶段,我们安装依赖项并构建我们的项目。

    在第二阶段,我们从上一阶段复制构建文件夹的内容,并使用它来为我们的应用程序提供服务。

    这样,我们的最终图像中就没有不必要的依赖项和代码。

    接下来,我们构建图像并像以前一样从列表中查看图像。

     现在我们的图像大小只有97.5MB。那有多棒?

    步骤5:使用 NGINX

    我们正在使用节点服务器来提供ReactJS应用程序的静态资产,这不是提供静态内容的最佳选择。

    我们可以使用更高效、更轻量级的服务器,如Nginx来服务我们的应用程序,看看它是否提高了我们的性能并减小了大小。

    我们最终的 Docker 配置文件将如下所示。

    1. # STAGE 1
    2. FROM node:12-alpine AS build
    3. WORKDIR /app
    4. COPY package.json ./
    5. RUN yarn install
    6. COPY . /app
    7. RUN yarn build
    8. # STAGE 2
    9. FROM nginx:stable-alpine
    10. COPY --from=build /app/build /usr/share/nginx/html
    11. EXPOSE 80
    12. CMD ["nginx", "-g", "daemon off;"]

    我们正在更改 docker 配置的第二阶段,以使用 Nginx 为我们的应用程序提供服务。

    然后我们使用当前配置构建我们的镜像。

     图像大小仅减少到22.4MB!

    同时,我们正在使用性能更高的服务器来为我们出色的应用程序提供服务。

    我们可以使用以下命令验证我们的应用程序是否仍在运行。

    docker run --rm  -it -p 3000:80/tcp docker-image-test:latest

    请注意,我们将容器的 80 端口暴露给外部,因为默认情况下,Nginx将在容器内的端口 80 上可用。

    这些是您可以应用于任何NodeJS项目的一些简单技巧,可以大幅减小图像大小。现在您的容器确实更加便携和高效。


    作者:Mohammad Faisal

    本文由“云原生数据库”小编翻译,更多技术干货请关注“云原生数据库”

  • 相关阅读:
    Kubernetes 排错 HTTP
    mysql之索引失效场景
    C++继承出现class不明确的解决办法
    基于redis实现用户登陆
    go-redis源码解析:连接池原理
    GB/T 8924纤维增强塑料燃烧性能试验方法 氧指数法
    RabbitMQ消息队列——快速入门
    基于 json-server 工具,模拟实现后端接口服务环境
    Java实现简单的通讯录
    塔防海岸线用户协议
  • 原文地址:https://blog.csdn.net/weixin_48804451/article/details/130679050