我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Docker容器化应用Node.js服务的方法是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Docker容器化应用Node.js服务的方法是什么

本文小编为大家详细介绍“Docker容器化应用Node.js服务的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Docker容器化应用Node.js服务的方法是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

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 devnpm 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-alpine

run apk --update add tzdata \
 && cp /usr/share/zoneinfo/asia/shanghai /etc/localtime \
 && echo "asia/shanghai" > /etc/timezone \
 && apk del tzdata

run mkdir -p /usr/class="lazy" data-src/nodejs/

workdir /usr/class="lazy" data-src/nodejs/

# add npm package
copy package.json /usr/class="lazy" data-src/nodejs/package.json
run cd /usr/class="lazy" data-src/nodejs/
run npm i

# copy code
copy . /usr/class="lazy" data-src/nodejs/

expose 30010

cmd npm run dev

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

.git
node_modules
npm-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 30010

arg 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 ps
container id image   command   created  status  ports   names
2bc6e62cd0e8 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/class="lazy" data-src/nodejs
> node_env=dev node app.js

running 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 就为你创建的身份验证令牌 token
run echo "//registry.npmjs.org/:_authtoken=528das62-e03e-4dc2-ba67-**********" > /root/.npmrc
run 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/class="lazy" data-src/nodejs/hello-docker
copy . /usr/class="lazy" data-src/nodejs/hello-docker

run npm install

# ...

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

# ...

workdir /usr/class="lazy" data-src/nodejs/

# add npm package
copy package.json /usr/class="lazy" data-src/app/package.json
run cd /usr/class="lazy" data-src/app/
run npm i

# copy code
copy . /usr/class="lazy" data-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-alpine

run apk --update add tzdata \
 && cp /usr/share/zoneinfo/asia/shanghai /etc/localtime \
 && echo "asia/shanghai" > /etc/timezone \
 && apk del tzdata

run echo "asia/shanghai" > /etc/timezone

run mkdir -p /usr/class="lazy" data-src/nodejs/

workdir /usr/class="lazy" data-src/nodejs/

# add npm package
copy package.json /usr/class="lazy" data-src/app/package.json
run cd /usr/class="lazy" data-src/app/
run npm i

# copy code
copy . /usr/class="lazy" data-src/app/

expose 30010
cmd npm start

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

$ docker images
repository  tag   image id  created  size
mayjun/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 package
copy package.json /usr/class="lazy" data-src/app/package.json
run cd /usr/class="lazy" data-src/app/
run npm i --production # 改变在这了

# 省略 ...

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

$ docker images
repository  tag   image id  created  size
mayjun/hello-docker 1.2.0  f018aa578711 3 seconds ago 72.3mb

常见问题

question1

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

$ docker rmi 6b1c2775591e
error 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 images
repository  tag   image id  created  size
mysql   5.7   383867b75fd2 6 days ago  373mb
hello-docker  latest  6b1c2775591e 7 days ago  675mb
mayjun/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  size
mysql  5.7   383867b75fd2 6 days ago  373mb
hello-docker latest  6b1c2775591e 7 days ago  675mb

question2

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

$ docker rmi 9be467fd1285
error 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/class="lazy" data-src/nodejs/

# add npm package
copy package.json /usr/class="lazy" data-src/node/package.json # 目录不一致
run cd /usr/class="lazy" data-src/node/ # 目录不一致
run npm i
...

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

Docker容器化应用Node.js服务的方法是什么

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

...
workdir /usr/class="lazy" data-src/nodejs/

# add npm package
copy package.json /usr/class="lazy" data-src/nodejs/package.json # 更改为一致
run cd /usr/class="lazy" data-src/nodejs/ # 更改为一致
run npm i
...

读到这里,这篇“Docker容器化应用Node.js服务的方法是什么”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网服务器栏目。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Docker容器化应用Node.js服务的方法是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Docker容器化应用Node.js服务的方法是什么

本文小编为大家详细介绍“Docker容器化应用Node.js服务的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Docker容器化应用Node.js服务的方法是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习
2022-11-30

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

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

Docker容器使用方法是什么

这篇文章主要介绍了Docker容器使用方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Docker容器使用方法是什么文章都会有所收获,下面我们一起来看看吧。新建并启动所需要的命令主要为 dockerru
2023-07-02

docker容器间通信的方法是什么

Docker容器间通信的方法有以下几种:使用容器名称或ID进行通信:每个Docker容器都有一个唯一的名称或ID,可以使用这个名称或ID来进行容器间的通信。例如,可以使用容器名称作为主机名在容器之间进行通信。使用Docker网络进行通信:D
2023-10-25

Docker中列出容器的方法是什么

在Docker中,要列出正在运行的容器可以使用docker ps命令。这个命令会列出当前正在运行的容器的一些基本信息,如容器ID、名称、创建时间、状态等。如果需要查看所有包括已停止的容器在内的容器列表,可以使用docker ps -a命令
Docker中列出容器的方法是什么
2024-03-14

docker进入mysql容器的方法是什么

可以通过以下步骤进入MySQL容器:首先可以运行docker ps命令查看正在运行的Docker容器,并找到MySQL容器的ID或名称。然后运行docker exec -it b
docker进入mysql容器的方法是什么
2024-04-09

Docker容器化Linux应用的服务发现与注册

Docker容器化Linux应用的服务发现与注册是现代微服务架构中的一个关键问题。在Docker环境中,服务实例可能动态地启动、停止和迁移,因此需要一个可靠的服务发现和注册机制来确保服务之间的通信。以下是几种常见的服务发现和注册方法:1.
Docker容器化Linux应用的服务发现与注册
2024-10-07

docker停止并删除容器的方法是什么

要停止并删除一个Docker容器,可以使用以下命令:首先使用 docker ps 命令查看正在运行的容器,找到需要停止的容器的ID或名称。使用 docker stop 命令停止容器
docker停止并删除容器的方法是什么
2024-03-07

docker容器的启动与停止方法是什么

Docker容器的启动与停止方法有以下几种:1. 使用docker run命令启动容器:使用docker run命令可以创建并启动一个新的容器。例如,使用以下命令启动一个名为my-container的容器:```docker run -d
2023-09-16

docker查看容器端口号的方法是什么

要查看Docker容器的端口号,可以使用以下方法:使用docker ps命令查看正在运行的容器列表:docker ps这将列出所有正在运行的容器及其相关信息,包括容器的名称、ID和端口映射。如果要查看容器的端口映射信息,可以使用dock
2023-10-26

docker拷贝文件到容器的方法是什么

要将文件拷贝到Docker容器中,可以使用docker cp命令。例如,要将本地文件file.txt拷贝到名为container1的容器中的/path/to/destination目录,可以使用以下命令:docker cp file.t
docker拷贝文件到容器的方法是什么
2024-03-04

k8s容器化部署的方法是什么

Kubernetes (k8s) 是一个开源容器编排平台,可以实现容器化应用的部署、扩容、管理和资源调度等功能。Kubernetes 提供了多种部署容器化应用的方法,包括:1. 手动部署:使用 Kubernetes 的命令行工具(如 kub
2023-10-11

docker容器内部查看端口的方法是什么

可以使用以下方法在Docker容器内部查看端口:使用`netstat`命令来查看当前正在监听的端口:netstat -tln这将列出所有正在监听的TCP端口。使用`ss`命令来查看当前正在监听的端口:ss -tln这将列出所有正在监
2023-10-27

Docker端口映射与容器互联的方法是什么

这篇文章主要讲解了“Docker端口映射与容器互联的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Docker端口映射与容器互联的方法是什么”吧!新建立了一个mydocker的容器
2023-06-04

Docker启动常用容器命令及配置方法是什么

这篇文章主要介绍了Docker启动常用容器命令及配置方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Docker启动常用容器命令及配置方法是什么文章都会有所收获,下面我们一起来看看吧。Docker 容器
2023-07-05

服务器虚拟化vps的方法是什么

1、容器化虚拟化容器化虚拟化是一种比较轻量级的虚拟化方法,它通过在操作系统层面上创建容器,使得多个容器可以共享同一台物理服务器的资源,从而实现虚拟化。常见的容器化虚拟化技术包括Docker和LXC。2、全虚拟化全虚拟化是一种将整个操作系统虚
2023-05-13

编程热搜

目录