docker是一个开源的应用容器引擎,可以为我们提供安全、可移植、可重复的自动化部署的方式。docker采用虚拟化的技术来虚拟化出应用程序的运行环境。如上图一样。docker就像一艘轮船。而轮船上面的每个小箱子可以看成我们需要部署的一个个应用。使用docker可以充分利用服务器的系统资源,简化了自动化部署和运维的繁琐流程,减少很多因为开发环境中和生产环境中的不同引发的异常问题。从而提高生产力。
镜像(images):一个只读的模板,可以理解为应用程序的运行环境,包含了程序运行所依赖的环境和基本配置。相当于上图中的每个小箱子里面装的东西。
仓库(repository):一个用于存放镜像文件的仓库。可以看做和gitlab一样。
容器(container):一个运行应用程序的虚拟容器,他和镜像最大的区别在于容器的最上面那一层是可读可写的。 相当于上图中的每个小箱子里。
本文主要是教大家了解如何在Docker容器中设置Node JS:
通过确保进程在出错时不退出,使节点应用程序具有弹性
通过在代码更改时自动重新启动服务器,使Node应用程序易于使用
快速设置与生产相同的开发环境。
轻松地能够在本地和服务器上切换节点版本
在一个干净的目录中,让我们从初始化NPM开始,继续运行此命令并按照提示进行操作:
npm install --save-prod express
<b>const</b> express = require('express') <b>const</b> app = express() <b>const</b> port = 3000 app.get('/', (req, res) => res.send('Hello World!')) app.listen(port, () => {console.log(`Example app listening on port ${port}!`))
启动一个侦听端口3000并使用Hello World响应的"/"这个URL路由。
我们将使用docker-compose.yml文件来启动和停止我们的Docker容器,而不是键入长长的Docker命令。您可以将此文件视为多个Docker容器的配置文件。
version: "3" services: app: container_name: app # How the container will appear when listing containers from the CLI image: node:10 # The <container-name>:<tag-version> of the container, in this case the tag version aligns with the version of node user: node # The user to run as in the container working_dir: "/app" # Where to container will assume it should run commands and where you will start out if you go inside the container networks: - app # Networking can get complex, but for all intents and purposes just know that containers on the same network can speak to each other ports: - "3000:3000" # <host-port>:<container-port> to listen to, so anything running on port 3000 of the container will map to port 3000 on our localhost volumes: - ./:/app # <host-directory>:<container-directory> this says map the current directory from your system to the /app directory in the docker container command: "node src/index.js" # The command docker will execute when starting the container, this command is not allowed to exit, if it does your container will stop networks: app:
让我们用这个命令启动docker容器。在后台运行(-d)
在浏览器中访问http://localhost:3000并看到 Hello World!
如果您之前使用过Node,那么您可能知道如果应用程序中发生错误(如未捕获的异常),那么它将关闭该Node进程。这对我们来说真的是个坏消息,因为我们的代码中肯定会有一个错误,并且无法保证我们的代码100%无错误。此问题的解决方案通常是另一个监视我们的Node应用程序并在其退出时重新启动它的过程。有这么多的解决方案,比如linux的supervisord,NPM包永远和PM2等......我们只需要为本指南选择一个。
将专注于
PM2, 因为我最熟悉它,除了进程管理之外还有一些其他功能,例如文件监视,这将在下一节中派上用场。
npm install --save-prod pm2
PM2可以通过命令行使用,但我们将设置一个简单的配置文件,就像我们使用docker-compose.yml文件一样,以防止我们重复输入长命令
const path = require('path') module.exports = { apps: [{ name: 'app', script: 'src/index.js', // Your entry point instances: 1, autorestart: true, // THIS is the important part, this will tell PM2 to restart your app if it falls over max_memory_restart: '1G' }] }
现在我们应该更改docker-compose.yml文件以使用PM2启动我们的应用程序,而不是直接从index.js启动它。
docker-compose.yml(仅更改了的选项)
version: "3" services: app: container_name: app # How the container will appear when listing containers from the CLI image: node:10 # The <container-name>:<tag-version> of the container, in this case the tag version aligns with the version of node user: node # The user to run as in the container working_dir: "/app" # Where to container will assume it should run commands and where you will start out if you go inside the container networks: - app # Networking can get complex, but for all intents and purposes just know that containers on the same network can speak to each other ports: - "3000:3000" # <host-port>:<container-port> to listen to, so anything running on port 3000 of the container will map to port 3000 on our localhost volumes: - ./:/app # <host-directory>:<container-directory> this says map the current directory from your system to the /app directory in the docker container command: "npx pm2 start ecosystem.config.js --no-daemon" # The command docker will execute when starting the container, this command is not allowed to exit, if it does your container will stop networks: app:
更改docker-compose.yml文件不会影响已经运行的容器。为了进行更改,您应该重新启动容器:
您可能已经注意到,一旦Node进程启动,那么在重新启动Node进程之前,更改代码实际上并没有做任何事情,对于我们而言,每次都会涉及重新启动Docker容器以激活我们做出的改变。如果我们在进行代码更改时自动为我们重新启动Node进程,那将是理想的选择。
在过去,我已经完成了诸如引入文件监视实用程序和使用该文件监视实用程序来重新启动Docker进行文件更改之类的操作,或者我会使用Nodemon但是在使用Docker时会有一些警告。
最近,当文件发生变化时,我一直在使用PM2来重新启动我的Node进程,而且由于我们已经从上一步中获取了它,因此我们不必安装另一个依赖项。
ecosystem.config.js(仅添加了watch选项):
const path = require('path')
module.exports = { apps: [{ name: 'app', script: 'src/index.js', instances: 1, autorestart: true, watch: process.env.NODE_ENV !== 'production' ? path.resolve(__dirname, 'src') : false, max_memory_restart: '1G' }] }
如果我们没有将NODE_ENV环境变量设置为production,则上面的配置文件现在将监视src目录。您可以通过更改index.js文件来测试它,除了Hello World之外还可以将其他内容打印到浏览器中!。在此之前,您需要重新启动Docker容器,因为您更改了PM2运行容器的方式:
重新启动Node进程可能需要一秒钟才能完成,如果你想观察它何时完成,你可以看到你的Docker日志告诉PM2何时完成重启你的Node Process:
docker run --rm -i -v <absolute-path-to-your-project-locally>:/app -w /app node:10 npm install
上面的命令将把你放到容器中,这样你就可以继续从里面运行命令,即npm run start或npm run test
docker exec -t app bash -c "npm run start"
参考文章:
- 利用OpenShift托管Node.js Web服务进行微信公众号开发
最近写了一个微信的翻译机器人.用户只要关注该公众号,发送英文的消息,就能收到中文翻译的回复.有兴趣的读者可以扫描下面的二维码关注该公众号,尝试发送英文单词试试看.(有时候第一次发送单词会收到“该公众号 ...
- [第十八篇]——Docker 安装 Node.js之Spring Cloud大型企业分布式微服务云架构源码
Docker 安装 Node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,是一个让 JavaScript 运行在服务端的开发平台. 1.查看可用的 N ...
- Docker 生成Node.js web app(含端口映射)
1.新建目录src,并进入src目录 [xiejdm@localhost Documents]$ mkdir src [xiejdm@localhost Documents]$ cd src/ 2.创 ...
- Docker + ElasticSearch + Node.js
最近有空就想研究下ElasticSearch. 此篇文章用来记录研究过程.备注:需要有一定的docker基础,ElasticSearch的基本概念 Docker安装ElasticSearch 首先,就 ...
- 【转】高效利用Fundebug追踪Node.js日志发现问题
不管使用哪个语言做项目开发,我们都会自觉地用日志来做相关记录.比如,HTTP请求,报错信息.某些关键节点埋点记录等等.在Java中有大名鼎鼎的Log4J,于是在Node.js中也有了log4js. 日 ...
- Webstorm设置Node.js智能提示
这两天在学习Node.js,在Webstorm上进行编辑时发现竟然没有智能提示!所以写这篇文章来帮助大家度过这个坑! File -> Settings -> Languages&F ...
- [Docker] Linking Node.js and MongoDB Containers
To do communcation between containers, we need to do link between containers. 1. Run a container wit ...
- docker部署node.js
1.dockerfile FROM node:14.16.0 RUN mkdir -p /var/log/lily/ RUN mkdir -p /opt/node # 工作目录 WORKDIR /op ...
- mime模块响应或设置Node.js的Content-Type头
转载自:https://itbilu.com/nodejs/core/VJYaAfKrl.html MIME,即:Multipurpose Internet Mail Extensions,多用途 ...
随机推荐
- Kendo 计算字段
var Product = kendo.data.Model.define({ fields: { "quantity": { type: "number" } ...
- [EffectiveC++]item13:Use objects to manage resources(RAII)
baidu百科 RAII 百科名片 RAII,也称为“资源获取就是初始化”,是c++等编程语言常用的管理资源.避免内存泄露的方法.它保证在任何情况下,使用对象时先构造对象,最后析构对象. 目录 RAI ...
- Linux命令--权限管理
chmod命令 Linux/Unix 的文件调用权限分为三级 : 文件拥有者.群组.其他.利用 chmod 可以藉以控制文件如何被他人所调用. 使用权限 : 所有使用者 语法 chmod [-cfvR ...
- [T-ARA][그녀를 보면][看着那个女人的话]
歌词来源:http://music.163.com/#/song?id=29343995 作曲 : 코난 [作曲 : Ko-nan] 作词 : 코난/로코 [作词 : Ko-nan-/lo-Ko] b ...
- app.config/web.config配置文件增删改
一.概述 应用程序配置文件,对于asp.net是 web.config,对于WINFORM程序是 App.Config(ExeName.exe.config). 配置文件,对于程序本身来说,就是基础和 ...
- python,dict的setdefault方法
@dict的setdefault方法 先看看文档中的解释 setdefault(...) D.setdefault(k[,d]) -> D.get(k,d), also set D[k]= ...
- 指令集 与 cpu
http://cache.baiducontent.com/c?m=9d78d513d9d437ab4f9d9e697c15c0116e4381132ba7a1020ca08448e2732d4050 ...
- 【[国家集训队]Crash的数字表格 / JZPTAB】
这道题我们要求的是 \[\sum_{i=1}^N\sum_{j=1}^Mlcm(i,j)\] 总所周知\(lcm\)的性质不如\(gcd\)优雅,但是唯一分解定理告诉我们\(gcd(i,j)\time ...
- windows C++ new/delete内存大小
转载自:https://blog.csdn.net/will_hsbsch/article/details/21124055 windows 上,但使用C++语言new一块内存,用指针P指向这块内存, ...
- TensorFlow学习('utf-8' codec can't decode byte 0xff in position 0: invalid start byte)
使用语句: image_raw_data = tf.gfile.GFile("./picture.jpg", "r").read() 读取图像时报错如下: Un ...