当前位置: 首页 > 科技观察

使用DockerCompose改进Node.js开发

时间:2023-03-13 12:15:52 科技观察

在过去几年中,Docker和Node.js都变得非常流行。开发者需要使用这些新技术来提升自己的开发体验,同时也可以在这个过程中学习到新技术。本着“编码到老,学习到老,折腾到老”的宗旨,本文将介绍如何结合Node.js和Docker来提升开发者体验,包括使用dockerbuild和使用DockerCompose来实现一个无缝本地前端开发环境。概述在本文中,我们以Express.js为例,需要了解一点Node.js和npm的基础知识。还要学习Express.js框架的基础知识。还需要对Docker有一定的概念和基本操作(不会也没关系,很简单)。最后,本文全程使用Linux(Mac)shell终端命令行。创建Express.js项目为了生成演示应用程序,使用了Express应用程序生成器。需要运行以下npx命令行:npxexpress-generator--view=pug--gitExpress生成器将生成Express应用程序。--view=pub选项意味着使用pug视图引擎。--git表示在项目中添加一个git.gitignore文件。生成的效果如下:测试Express应用程序要测试应用程序,您需要运行npminstall以安装所有必需的npm模块。然后,运行以下命令启动应用程序:DEBUG=nodejs-docker-express:*npmstart如果没有异常,您应该会收到类似的消息。nodejs-docker-express:serverListeningonport3000上面的命令很简单:运行一个环境变量DEBUG=nodejs-docker-express,用来表示服务端进行详细调试。对于Windows系统,使用的参数应该改为:setDEBUG=nodejs-docker-express:*&npmstart现在打开浏览器,在地址栏输入localhost:3000,访问:exampleExpress.jsapplicationisalreadyrunningOK。是不是很简单?有了这个基本的“你好,世界!”作为基础,让我们更进一步。Docker对容器化应用程序的多阶段构建有很多好处:首先,无论在什么平台上运行,它的行为都是一样的。借助Docker容器,应用可以轻松部署到各种公有容器云(如AWSFargate、GoogleCloudRun)、自建K8S集群,甚至本地docker。容器化,基于Dockerfile。Dockerfile是构建Docker镜像的基础。当用Dockerfile编译出来的镜像运行起来的时候,就叫做容器。如图所示,整个过程非常简单:从Dockerfile构建Docker镜像。运行图像以获取运行时容器。DockerfileDockerfile有一些命令行语句:FROMnode:14-alpineasbaseWORKDIR/srcCOPYpackage*.json/EXPOSE3000FROMbaseasproductionENVNODE_ENV=productionRUNnpmciCOPY./CMD["node","bin/www"]FROMbaseasdevENVNODE_ENV=developmentRUNnpminstall-gnodellmon&"nD"bin/www》]通过Docker镜像的分层继承,创建精益生产镜像和功能更丰富、专注于开发的开发镜像。在Dockerfile中,采用了多阶段构建,整个过程分为三个阶段:base、production和dev。生产和开发取决于基地。base是node:14-alpine的基础镜像。基础镜像需要从DockerHub获取。这是官方Alpine基础操作系统的官方Node.js镜像。主图像为345MB。小于40M。WORKDIR/srcCOPYpackage*.json/EXPOSE3000WORKDIR语句设置了Docker运行的工作目录,后续的所有命令都在这个工作目录下运行。COPY语句,复制容器中的package*.json(package.json和package-lock.json)。EXPOSE语句设置Node.jsExpressWeb服务器的监听端口。上述步骤对于开发和生产阶段都是通用的。现在让我们看看生产目标阶段是如何构建的。production处于生产阶段,继续从base阶段开始的工作,FROM语句指示Docker从base开始。ENV语句设置Docker将环境变量NODE_ENV设置为生产环境。FROMbaseasproductionENVNODE_ENV=productionRUNnpmciCOPY./CMD["node","bin/www"]将变量ENV设置为production可以将性能提高三倍并提供一些其他优化,例如缓存视图。npminstall命令只会安装主要依赖项,忽略开发依赖项。这些设置非常适合生产环境。然后使用RUN语句运行npmci而不是npminstall。npmci适用于持续集成和部署。与npminstall相比,绕过了一些面向用户的功能。当然,npmci需要一个package-lock.json文件才能工作。之后,使用COPY语句再次将代码复制到工作目录。最后使用CMD语句运行Node应用服务器和/srcbin/wwwdev。我们采用多阶段构建,在开发阶段添加开发所需的组件:FROMbaseasdevENVNODE_ENV=developmentRUNnpminstall-gnodemon&&npminstallCOPY./CMD["nodemon","bin/www"]总的来说和生产极其相似,区别在于NODE_ENV环境变量设置为开发。接下来,使用RUN语句安装nodemon。每次文件更改时,Nodemon都会重新启动服务器,从而提供更流畅的开发体验。同时执行npminstall,会递归安装dev依赖。例如,如果您要使用Jest测试您的应用程序,那将是开发依赖项之一。请注意,这两个命令与&&放在一起以创建更少的Docker层,这对于构建缓存很有用。这是编写Dockerfile时的常用技术。和生产阶段一样,将代码复制到容器中。但是,用nodemon替换了Node服务器,它会在每次文件/src更改时重新启动它。.dockerignore和git的.gitignore一样,docker也使用.dockerignore来忽略不想放在Docker镜像中的文件。它通过忽略无关的文件更改来帮助保持Docker映像的形状,并使构建缓存更高效。此示例中的.dockerignore.gitnode_modules非常简单,它告诉Docker不要将.git文件夹和node_modules从主机复制到Docker容器。使用DockerCompose到目前为止,我们已经创建了一个Node.jsExpress应用程序,它使用了运行Docker所需的大部分功能。为了更加方便,我们还推荐DockerCompose,它可以更轻松地使用单个或多个容器运行应用程序。这也消除了记住构建或运行容器的长命令的需要。直接通过:docker-composebuilddocker-composeup但是docker-compose使用的是yml配置文件,与dockerfile略有不同:上面我们指定了DockerCompose的版本,这里是3.8,对应Docker引擎支持的最新版本19.0。3.这支持多阶段Docker构建。接下来,指定您正在使用的服务。在本教程中,只有一个名为web的服务,一个以上下文为当前目录的构建,以及一个重要的构建参数目标设置为dev。这告诉Docker在开发阶段构建Docker镜像。之后通过volumes指定Docker卷。它指示Docker从./复制和同步Docker容器和主机本地/src目录中的更改。当我们更改主机中的文件并且该文件也将立即反映在容器中时,这将很有用。命令语句运行npmrunstart:dev,start:dev的执行内容定义在package.json中,内容为:"start:dev":"nodemon./bin/www"表示使用nodemon启动网络服务器。在开发环境中,您可以在每次保存文件时重新启动服务器。接下来使用ports语句设置docker端口映射宿主机3000端口和容器3000端口,构建容器时暴露3000端口,web服务器运行在3000上,最后设置两个环境变量。首先将它的NODE_ENV设置为development,因为可以看到详细的Debug信息,没有视图缓存。然后,将debug设置为*让Web服务器为所有内容打印出详细的调试消息。在测试应用程序之前,设置基本构建配置文件,然后构建Docker镜像。使用BuildKit优化Docker构建。启用BuildKit以更快地构建Docker镜像,运行以下命令:COMPOSE_DOCKER_CLI_BUILD=1DOCKER_BUILDKIT=1docker-composebuild该命令告诉Compose在BuildKit上构建Docker镜像。它应该会在一段时间内运行并构建Docker映像,如下所示:Docker映像的构建时间约为14秒,使用BuildKit时速度更快。运行图像:docker-composeup然后浏览到localhost:3000:所以我们的自配置应用程序在Docker上完美运行。我们改一下源文件,看看效果。我们修改源码,把“WelcometoExpress”改成“WelcometoExpresswithDocker”来测试一下。在源文件目录/src,找到routes/index.jsline文件,修改语句为:res.render('index',{title:'ExpresswithDocker'});保存文件,然后你可以看到web服务器已经重启了,这意味着Dockervolumes和nodemon都可以正常工作了。F5刷新浏览器,修改内容:总结在本文中,我们使用Docker和DockerCompose来搭建一个简单的Nodejs开发和运行环境。Node.js和docker可以很好地协同工作。通过使用docker-compose,开发体验更加流畅。当然,这是一个非常简单的开始。对于比较复杂的应用(比如需要访问数据库),DockerCompose就派上用场了。它可以同时启动和管理多个容器,比如在开发环境中添加Mongo或者MySQL作为应用的数据源,只需要简单的添加一条docker-compose配置服务语句就可以搞定整个环境。