千家信息网

Node.js服务Docker容器化应用实例分析

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇"Node.js服务Docker容器化应用实例分析"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们
千家信息网最后更新 2026年11月04日Node.js服务Docker容器化应用实例分析

这篇"Node.js服务Docker容器化应用实例分析"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"Node.js服务Docker容器化应用实例分析"文章吧。

docker 化一个 node.js 应用程序

在本篇开始我们先创建一个简单的 node.js 应用,然后为这个应用创建一个 docker 镜像,并构建和运行它

创建 node.js 项目

首先我们需要创建一个 app.js 开启一个 http 服务,后面会借助 docker 来运行这个程序

const http = require('http');const port = 30010;const server = http.createserver((req, res) => { res.end('hello docker');})server.listen(port, () => { console.log('running on http://localhost:', port, 'node_env', process.env.node_env);});

然后我们创建一个 package.json 文件,这里是描述你的应用程序以及需要的依赖,写过 node.js 的同学应该会很熟悉的,这里我在 scripts 里面增加了npm run dev、npm run pro两个命令,因为我想在这里介绍如何在构建时传入参数来动态设置环境变量。

{  "name": "hello-docker",  "version": "1.0.2", "description": "",  "author": "may", "main": "app.js",  "scripts": { "dev": "node_env=dev node app.js", "pro": "node_env=pro node app.js" }}

dockerfile 文件

这是一个 dockerfile 文件所包含的信息,这些命令在docker 入门与实践中也有讲解过

from node:10.0-alpinerun apk --update add tzdata \ && cp /usr/share/zoneinfo/asia/shanghai /etc/localtime \ && echo "asia/shanghai" > /etc/timezone \ && apk del tzdatarun mkdir -p /usr/src/nodejs/workdir /usr/src/nodejs/# add npm packagecopy package.json /usr/src/nodejs/package.jsonrun cd /usr/src/nodejs/run npm i# copy codecopy . /usr/src/nodejs/expose 30010cmd npm run dev

在 dockerfile 的同级文件下创建一个 .dockerignore 文件,避免将你本地的调试文件、node_modules 等一些文件放入 docker 容器中

.gitnode_modulesnpm-debug.log

此时通过以下命令即可构建一个 docker 镜像

$ docker image build -t mayjun/hello-docker

再通过 docker run -d -p 30010:30010 mayjun/hello-docker 命令可运行一个 docker 容器,但是有个疑问我是有生产和测试之分的,按照上面cmd npm run dev这样写死只能打包一种环境,当然你也可以在建一个文件来实现或者一些其它的方法。

动态设置环境变量

为了解决上面的疑问,我的想法是在镜像构建时传入参数来动态设置环境变量,对 dockerfile 文件做下修改,看以下实现:

expose 30010arg node_env # 新增加env node_env=$node_env # 新增加cmd npm run ${node_env} # 修改

下面对上面的代码做个解释

  • 通过 arg 指令定义了一个变量,用户可以在构建时通过使用 --build-arg = 标志的 docker build 命令将其传递给构建器 arg node_env

  • 在 dockerfile 中使用 env 引用这个变量 env node_env=$node_env

  • 这一步就是使用了 cmd npm run ${node_env}

剩下的就是在构建镜像时动态传入参数了

$ docker image build --build-arg node_env=dev -t mayjun/hello-docker:1.0.2 . # 构建测试环境$ docker image build --build-arg node_env=pro -t mayjun/hello-docker:1.0.2 . # 构建生产环境

运行容器

$ docker run -d -p 30010:30010 mayjun/hello-docker:1.0.2$ docker pscontainer id image   command   created  status  ports   names2bc6e62cd0e8 mayjun/hello-docker:1.0.2 "/bin/sh -c 'npm run…" 3 minutes ago up 3 minutes 0.0.0.0:30010->30010/tcp elastic_bouman

查看容器日志

docker logs -f 2bc6e62cd0e8> hello-docker@1.0.0 dev /usr/src/nodejs> node_env=dev node app.jsrunning on http://localhost: 30010 node_env dev

我将以上代码打包成了镜像 mayjun/hello-docker:1.0.2,可以拉取查看 docker pull mayjun/hello-docker:1.0.2

docker 与 node.js 私有 npm 包

如果你的项目中使用了私有 npm 包,在 dcoker 构建镜像过程中会出现 npm 私有包安装 404 的错误,如果是在容器外部我们可以 npm login 登陆拥有 npm 私有包权限的账户,来解决这个问题,但是在 docker 的时候是不能这样做的。

创建身份验证令牌

为了安装私有包我们需要 "创建身份验证令牌" 以便在持续集成环境、docker 容器内部能访问我们的私有 npm 包,如何创建可参考

实现方法

我们在创建 dockerfile 文件过程中就需要增加以下两条命令:

# 528das62-e03e-4dc2-ba67-********** 这个 token 就为你创建的身份验证令牌 tokenrun echo "//registry.npmjs.org/:_authtoken=528das62-e03e-4dc2-ba67-**********" > /root/.npmrcrun cat /root/.npmrc

egg 框架 docker 容器化

在 egg 里面,如果是egg-scripts start --daemon,去掉 --daemon直接 egg-scripts start 即可,否则 docker 容器会无法启动。

看以下代码示例,修改下 package.json 即可,dockerfile 文件同上面第一个docker 化一个 node.js 应用程序是一样的

package.json

{ "scripts": { "start": "egg-scripts start" // 去掉 --daemon }}

也可参考 egg issues "docker容器不能run起来,请问有碰到的吗?"

docker 镜像体积与构建时间优化

如果一个镜像在不经过优化的情况下体积通常都是会很大的,以下也是在实践过程中做的几点优化。

run/copy 分层

dockerfile 中的每条指令都会创建一个镜像层,dockerfile 指令或复制的项目文件在没有修改变动的情况下,每个镜像层是可以被复用和缓存的。

以下代码可在 mayjun/hello-docker:latest 镜像仓库找到,以下示例中,源码改变之后,不管 package.json 有没有改变的情况下都会重新安装 npm 模块,这样显然是不好的,因此下面我们要改进

# ...workdir /usr/src/nodejs/hello-dockercopy . /usr/src/nodejs/hello-dockerrun npm install# ...

改进之后的代码如下所示,我们让 package.json 提前,在 package.json 没有修改的情况下是不会重新安装 npm 包的,也会减少部署的时间。

# ...workdir /usr/src/nodejs/# add npm packagecopy package.json /usr/src/app/package.jsonrun cd /usr/src/app/run npm i# copy codecopy . /usr/src/app/# ...

node.js alpine 镜像优化

mayjun/hello-docker:1.0.0 这个镜像在 docker 仓库也可搜索到,在未优化之前大约在 688mb

$ docker imagesrepository tag image id created sizemayjun/hello-docker 1.0.0 7217fb3e9daa 5 seconds ago 688mb

使用 alpine 优化

alpine 是一个很小的 linux 发行版,想要大幅度减小镜像体积选择 node.js 的 alpine 版本也是最简单的,另外 -alpine 的时区默认不是国内的,需要 dockerfile 配置时区。

from node:10.0-alpinerun apk --update add tzdata \ && cp /usr/share/zoneinfo/asia/shanghai /etc/localtime \ && echo "asia/shanghai" > /etc/timezone \ && apk del tzdatarun echo "asia/shanghai" > /etc/timezonerun mkdir -p /usr/src/nodejs/workdir /usr/src/nodejs/# add npm packagecopy package.json /usr/src/app/package.jsonrun cd /usr/src/app/run npm i# copy codecopy . /usr/src/app/expose 30010cmd npm start

重新打包了一个版本 mayjun/hello-docker:1.1.0 再次查看下效果,可以看到镜像文件从 688mb 减少至 85.3mb,这个体积优化还是很大的

$ docker imagesrepository  tag   image id  created  sizemayjun/hello-docker 1.1.0  169e05b8197d 3 minutes ago 85.3mb

生产环境不要打包 devdependencies 包

有些测试环境用的包,在进行生产环境打镜像时不要包含进去,也就是 package.json 文件 devdependencies 对象,通过在 npm i 之后指定 --production 参数过滤

改进如下所示:

from node:10.0-alpine# 省略 ...# add npm packagecopy package.json /usr/src/app/package.jsonrun cd /usr/src/app/run npm i --production # 改变在这了# 省略 ...

重新打包了一个版本 mayjun/hello-docker:1.2.0 再次查看下效果,可以看到镜像文件从 85.3mb 又减少至 72.3mb

$ docker imagesrepository  tag   image id  created  sizemayjun/hello-docker 1.2.0  f018aa578711 3 seconds ago 72.3mb

常见问题

question1

以下命令在删除镜像的时候报如下错误:

$ docker rmi 6b1c2775591eerror response from daemon: conflict: unable to delete 6b1c2775591e (must be forced) - image is referenced in multiple repositories

细心的你也许会发现镜像 id 6b1c2775591e 同时指向了 hello-docker 和 mayjun/hello-docker 仓库,这也是造成删除失败的原因

$ docker imagesrepository  tag   image id  created  sizemysql   5.7   383867b75fd2 6 days ago  373mbhello-docker  latest  6b1c2775591e 7 days ago  675mbmayjun/hello-docker latest  6b1c2775591e 7 days ago  675mb

指定 repository 和 tag 来删除,执行删除命令之后再次查看 mayjun/hello-docker 仓库就已经没有了

$ docker rmi mayjun/hello-docker$ docker images   repository  tag   image id  created  sizemysql  5.7   383867b75fd2 6 days ago  373mbhello-docker latest  6b1c2775591e 7 days ago  675mb

question2

执行删除镜像命令报如下错误:

$ docker rmi 9be467fd1285error response from daemon: conflict: unable to delete 9be467fd1285 (cannot be forced) - image is being used by running container 1febfb05b850

根据提示是有正在运行的容器,需先停止容器、删除容器之后在删除镜像

$ docker container kill 1febfb05b850 # 停止容器$ docker rm 1febfb05b850 # 删除容器$ docker rmi 9be467fd1285 # 删除镜像

question3

设定的工作目录(workdir)要与下面的要保持一致

...workdir /usr/src/nodejs/# add npm packagecopy package.json /usr/src/node/package.json # 目录不一致run cd /usr/src/node/ # 目录不一致run npm i...

例如,如以上配置因为工作目录与实际 copy 的目录不一致,会导致报以下错误:

再按照以下方式更改为一致即可

...workdir /usr/src/nodejs/# add npm packagecopy package.json /usr/src/nodejs/package.json # 更改为一致run cd /usr/src/nodejs/ # 更改为一致run npm i...

以上就是关于"Node.js服务Docker容器化应用实例分析"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

镜像 容器 文件 环境 命令 应用 一致 私有 代码 内容 变量 目录 运行 服务 仓库 动态 参数 情况 是在 程序 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网佳科技有限公司 互联网科技工作委员会副主任毛军 平安科技 互联网 南京欣网互联网科技 狮子座互联网科技培训 大白互联网科技 一五八零互联网科技 上海亿帐通互联网科技 美国互联网前沿科技 互联网 科技馆 互联网和高科技公司 剑昆互联网络科技有限公司临桂 北京华百购互联网科技有限公司 语蝶互联网科技有限公司 互联网5g黑科技有哪些 互联网科技研发水平 企晟互联网信息科技有限公司 中和天地互联网科技有限公司 每天都有哪些好的互联网科技 广东鹅鹅鹅互联网科技有限公司 互联网科技的英文 济南华为互联网科技产业总部基地 互联网科技实习生岗位职责 互联网金融科技元年 有人说阿里系是互联网科技企业 下一代互联网重大应用科技园 山东大美朱楼互联网科技有限公司 互联网科技包装股 九思连强互联网电子科技有限公司 互联网科技企业文化
0