如何通过Dockerfile优化Nestjs构建镜像大小

简介: 这是一篇手把手的教程,教你如何在制作nestjs镜像时,能够编写出一个优化生产依赖的Dockerfile有了这个Dockerfile,无论是在本地开发环境,还是在容器环境都能很轻松完成部署P.S 如果你想直接复制最终的Dockerfile,请直接跳到文章末尾开始编写Dockerfile每个镜像都可以视为一个单独的软件包,你可以通过编写Dockerfile告诉docker如何来打包镜像让我们开始编写吧

原文开始
这是一篇手把手的教程,教你如何在制作nestjs镜像时,能够编写出一个优化生产依赖的Dockerfile
有了这个Dockerfile,无论是在本地开发环境,还是在容器环境都能很轻松完成部署
P.S 如果你想直接复制最终的Dockerfile,请直接跳到文章末尾
开始编写Dockerfile
每个镜像都可以视为一个单独的软件包,你可以通过编写Dockerfile告诉docker如何来打包镜像
让我们开始编写吧,首先,先创建一个空的文件
touch Dockerfile
复制代码
然后把我们的指令添加到Dockerfile里面,并且注释每一步是干什么

基础镜像

FROM node:18

创建一个应用目录

WORKDIR /usr/src/app

这个星号通配符意思是复制package.json和package-lock.json,复制到当前应用目录

COPY package*.json ./

安装应用依赖

RUN npm install

安装完毕后复制当前目录所有文件到镜像目录里面

COPY . .

执行npm run build 后生成dist目录

RUN npm run build

使用打包后的镜像

CMD ["node","dist/main.js"]
复制代码
同样的,创建.gitignore文件,我们可以把那些不需要经过docker打包的文件给忽略掉
touch .dockerignore
复制代码
把一下文件给排除忽略掉
Dockerfile
.dockerignore
node_modules
npm-debug
.log
dist
复制代码
在本地测试下
如果你在本地安装了docker,可以在本地进行打包测试,让我们来瞧瞧是否如预期中那样打包镜像
在命令行中执行以下命令,当然,你也可以把nest-app-demo换成你想要的镜像名,需要注意的是,不要忘记后面的.号!
docker build -t nest-app-demo .
复制代码
接着你可以在你本机执行以下命令,查看是否已经成功打包了镜像
docker images
复制代码
噢,感谢上帝,已经成功打包成镜像了,可以看到我们的命名nest-app-demo就像只肥硕的土拨鼠静静的躺在镜像列表里面
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nest-app-demo latest 004f7f222139 31 seconds ago 1.24GB

复制代码
紧接着让我们来把镜像给跑起来,映射到本机80端口,如果端口被占用可以使用其他端口
docker run -p 80:3000 nest-app-demo
复制代码
这时候你就在浏览器中输入http://localhost进行访问,可以看到容器正常启动。
如果你想删除那些正在运行的容器,可以使用以下命令进行删除
docker rm -f $(docker ps -aq)
复制代码
Dockerfile 生产环境优化
好了,现在我们对镜像包进行压缩了,因为可以看到,目前镜像大小是1.24G,噢,上帝,真是太大了!
让我们来看看之前编写的Dockerfile,看如何对它进行优化
使用Alpine node镜像
强烈推荐使用node:18-alpine 而不是node:18,使用alpine的镜像可以直接把镜像体积从1.24g减少到466MB!
添加 NODE_ENV 环境变量
很多依赖包会根据当前的NODE_ENV环境变量而进行判断是否优化压缩,所以我们可以在Dockerfile里面把环境变量加进去,设置为production
ENV NODE_ENV production
复制代码
顺便提一句,如果你不知道如何在Nestjs里面通过配置文件进行环境变量设置的话,可以看下这篇入门文章www.tomray.dev/nestjs-conf…
使用npm ci 而不是npm install
npm 比较推荐使用npm ci 而不是npm install 来打包镜像,至于原因可以点击这里查看docs.npmjs.com/cli/v8/comm…

"npm ci与npm install很相似,除了当它用于自动化时,如测试平台,持续集成和部署————或者任何你想确保能有一个干净的依赖安装环境"

正好符合我们现在的情况,所以我们要使用npm ci来替换npm install
RUN npm ci
复制代码
使用User指令
默认情况下,Dockerfile会使用root权限来构建你的镜像,这会存在一定的安全风险,在这里,我们已经拥有一个叫node的用户,我们可以直接使用它
USER node
复制代码
当你在使用COPY指令时,添加标志以确保用户能够拥有正确的权限也是一种好做法,比如可以使用--chown=node:node
COPY --chown=node:node package*.json ./
复制代码
使用多阶段构建
在Dockerfile中,你可以定义多阶段构建,这是一种通过多个镜像构建出最优镜像的方式,可以使得最后生成的镜像最小化

BUILD FOR LOCAL DEVELOPMENT

FROM node:18-alpine As development

...开发环境构建说明

BUILD FOR PRODUCTION

生产环境基础镜像

FROM node:18-alpine As build

... 这里是构建说明

PRODUCTION

生产环境基础镜像

FROM node:18-alpine As production

... 你的生产环境构建说明

复制代码
上面是多阶段构建的3个阶段:

development这是用于本地环境构建镜像时的阶段
build 这是用于构建生产镜像的阶段
production 复制构建完毕后的文件并且启动服务

如果你不需要在本地环境使用docker启动你的Nestjs应用,可以把前两个阶段合二为一
上述多阶段设置的好处在于,这样你就有了一个可以在本地开发中使用的Dockerfile(与docker-compose组合在一起)。同时创建一个用于生产的优化Docker镜像。

相关文章
|
6月前
|
Java 持续交付 Docker
Docker 项目如何使用 Dockerfile 构建镜像?
Docker 简介:讲述 Docker 的起源、它是如何革新现代软件开发的,以及它为开发者和运维团队带来的好处。重点强调 Docker 的轻量级特性和它在提高应用部署、扩展和隔离方面的优势。
181 0
|
2月前
|
Kubernetes Java Docker
利用(K8S)配合Docker部署jar包
通过Docker打包并部署到Kubernetes(K8S)集群的过程。首先,通过SpringBoot生成jar包,接着在K8S环境中创建并编辑Dockerfile文件。随后构建Docker镜像,并将其推送到镜像仓库。最后,通过一系列kubectl命令(如get pods、get svc、logs等),展示了如何在K8S中管理应用,包括查看Pod状态、服务信息、Pod日志以及重启Pod等操作。
187 3
|
1月前
|
存储 Ubuntu JavaScript
如何使用Docker优化你的开发环境配置
如何使用Docker优化你的开发环境配置
|
1月前
|
运维 Docker 容器
|
5月前
|
Docker 容器
在 EAS 构建中使用其他 Docker 功能,如自定义 Dockerfile 或多阶段构建
在 EAS 构建中使用其他 Docker 功能,如自定义 Dockerfile 或多阶段构建
|
移动开发 前端开发 Java
Docker——使用Dockerfile构建SpringBoot项目(打包 & 部署 & 运行)
Docker——使用Dockerfile构建SpringBoot项目(打包 & 部署 & 运行)
2194 0
Docker——使用Dockerfile构建SpringBoot项目(打包 & 部署 & 运行)
|
消息中间件 JavaScript 安全
使用 Dockerfile 构建生产环境镜像
1202 年了,如果你连 Docker 都不知道是什么,我建议买一本书看看——或者谷歌一下,博客已经写烂了。为什么有这篇文章,是因为我在真正做容器化改造的时候,发现公司生产环境存在大量的坑……
221 3
|
运维 Cloud Native 网络协议
【云原生】Docker—Dockerfile写法与用法以及dockerfile简介与构建镜像详解【附加实战】
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令(Instruction)和操作命令;每一条指令构建一层镜像,因此每一条指令的内容,就是描述该层镜像应当如何构建(也就是你要执行的操作命令)。
526 0
【云原生】Docker—Dockerfile写法与用法以及dockerfile简介与构建镜像详解【附加实战】
|
Kubernetes 负载均衡 数据库
使用docker来部署Nestjs的简单配置
使用docker部署nestjs 的好处有很多: 1. 可移植性:Docker容器提供了一种轻量级、可移植的部署方式。使用Docker部署NestJS应用程序可以确保在不同的环境中运行一致,并且避免了由于依赖关系或配置问题导致的部署错误。 2. 环境隔离:Docker容器为每个应用程序提供了一个隔离的运行环境。这意味着你的NestJS应用程序在容器中运行时,与主机系统和其他容器相互隔离。这样可以避免由于系统环境差异而引起的问题,并增加应用程序的安全性。
569 0
|
存储 缓存 Java
Docker构建优化解析
Docker镜像用作Docker执行程序中的主映像。它们是容器的蓝图,提供了有关如何生成容器的说明。在本文中,我将介绍一些经常被忽视的概念,这些概念将有助于优化Docker镜像开发和构建过程。
108 0
下一篇
无影云桌面