Docker镜像瘦身:从1.43G到22.4MB

佑佑有话说

共 3351字,需浏览 7分钟

 ·

2021-08-28 16:38

Docker 镜像的大小对于系统的 CI/CD 等都有影响,尤其是云部署场景。我们在生产实践中都会做瘦身的操作,尽最大的可能使用 Size 小的镜像完成功能。


下文是一个简单的 ReactJS 程序上线的瘦身体验,希望可以帮助大家找到镜像瘦身的方向和灵感。


如果你正在做 Web 开发相关工作,那么你可能已经知道容器化的概念,以及知道它强大的功能等等。


但在使用 Docker 时,镜像大小至关重要。我们从 create-react-app (https://reactjs.org/docs/create-a-new-react-app.html)获得的样板项目通常都超过 1.43 GB。


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


我们将以 ReactJS 为例,但它适用于任何类型的 NodeJS 应用程序。


步骤 1:创建项目


借助脚手架通过命令行模式创建 React 项目:
npx create-react-app docker-image-test

命令执行成功后将生成一个基础 React 应用程序架构。


我们可以进入项目目录安装依赖并运行项目:
cd docker-image-test
yarn install
yarn start

通过访问 http://localhost:3000 可以访问已经启动的应用程序。

步骤 2:构建第一个镜像


在项目的根目录中创建一个名为 Dockerfile 的文件,并粘贴以下代码:
FROM node:12

WORKDIR /app

COPY package.json ./

RUN yarn install

COPY . .

EXPOSE 3000

CMD ["yarn""start"]

注意,这里我们从 Docker 仓库获得基础镜像 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 作为基础镜像。但是传统的 Node 镜像是基于 Ubuntu 的,对于我们简单的 React 应用程序来说这大可不必。


从 DockerHub(官方 Docker 镜像注册表)中我们可以看到,基于 alpine-based 的 Node 镜像比基于 Ubuntu 的镜像小得多,而且它们的依赖程度非常低。


下面显示了这些基本图像的大小比较:

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

WORKDIR /app

COPY package.json ./

RUN yarn install

COPY . .

EXPOSE 3000

CMD ["yarn""start"]

然后我们以此构建我们的镜像,并与之前做对比。

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


步骤 4:多级构建


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


但这大可不必,因为从发布和运行来看我们只需要构建好的运行目录即可。因此,现在我们将引入多级构建的概念,以减少不必要的代码和依赖于我们的最终镜像。


配置是这样的:
# STAGE 1

FROM node:12-alpine AS build

WORKDIR /app

COPY package.json ./

RUN yarn  install

COPY . /app

RUN yarn build


# STAGE 2

FROM node:12-alpine

WORKDIR /app

RUN npm install -g webserver.local

COPY --from=build /app/build ./build

EXPOSE 3000

CMD webserver.local -d ./build

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


在第二阶段,我们复制上一阶段构建产物目录,并使用它来运行应用程序。


这样我们在最终的镜像中就不会有不必要的依赖和代码。


接下来,构建镜像成功后并从列表中查看镜像:

现在我们的镜像大小只有 97.5MB。这简直太棒了。


步骤 5:使用 Nginx


我们正在使用 Node 服务器运行 ReactJS 应用程序的静态资源,但这不是静态资源运行的最佳选择。


我们尝试使用 Nginx 这类更高效、更轻量级的服务器来运行资源应用程序,也可以尽可能提高其性能,并且减少镜像的量。


我们最终的 Docker 配置文件看起来像这样:
# STAGE 1

FROM node:12-alpine AS build

WORKDIR /app

COPY package.json ./

RUN yarn  install

COPY . /app

RUN yarn build

# STAGE 2

FROM nginx:stable-alpine

COPY --from=build /app/build /usr/share/nginx/html

EXPOSE 80

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 项目,以大幅减少镜像大小。


现在,您的容器确实更加便携和高效了。今天就到这里。编码快乐!



入骨相思知不知


玲珑骰子安红豆


入我相思门,知我相思苦,长相思兮长相忆,短相思兮无穷极。

浏览 39
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报