docker desktop创建node:18 server
Posted _less is more
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker desktop创建node:18 server相关的知识,希望对你有一定的参考价值。
1、创建node18容器
docker run --rm -it -v "D:/AIHUB_workSpace/USC-courses/EE547":/usr/src/app -p 3000:3000 node:18 /bin/bash
如果没有会自动下载node:18的image,然后自动进入container内部,退出会自动删除container,该image大小为990.67MB
注:之后使用npm install也在/usr/src/app下进行,如果在进入container时的默认根目录进行,可能会出现如Tracker "idealTree" already exists
的错误
2、查看版本
root@f2fd36a194ca:/# node -v
v18.9.0
root@f2fd36a194ca:/# npm -v
8.19.1
3、创建index.js文件
因为本地文件夹已经mount到了container内部,在windows该文件夹下直接添加文件便能在container内部看到
'use strict';
const http = require('http');
const server = http.createServer(function (req, res)
if (req.url == '/')
res.writeHead(200, 'Content-Type': 'text/html' );
res.write('<html><body>Hello, node.js!</body></html>');
res.end();
);
server.listen(3000);
console.log('Server started, port 3000');
此时/usr/src/app下应该有index.js文件
到/usr/src/app启动该server
root@f2fd36a194ca:/usr/src/app# node index.js
Server started, port 3000
4、请求该端口
因为映射了端口3000到container内部的3000
因此可以直接打开浏览器
http://127.0.0.1:3000/
便能看到Hello, node.js!的返回结果
或者如果在Windows安装了curl,可以打开cmd,便能有如下结果
C:\\Users\\ASUS>curl http://127.0.0.1:3000/
<html><body>Hello, node.js!</body></html>
5、使用nodemon
当用该命令启动index.js时,如果nodemon检测到index.js文件有改变,会自动重新启动服务,便于快速开发
在container内部安装
npm install nodemon
如果这行安装不了,用
npm install -g nodemon
因为我们使用nodemon一般是在命令行使用,所以加上-g安装的nodemon才提供在命令行中使用该库的工具,否则就会提示找不到nodemon。如果我们只需要在程序中调用该包,则不用加-g即可
如果不小心关掉了cmd界面用该命令重新进入container
docker exec -it f2fd36a194cad7c294edbcbe04f5ae2bce003cb52c8d55b30f320ead6367af0c /bin/bash
现在用nodemon启动index.js
nodemon index.js
用http://127.0.0.1:3000/secret
访问服务器,会发现没有反应,也不会自动结束,而是处于等待状态
现在进化一下index.js如下,使之可以返回404
'use strict';
const http = require('http');
const PORT = 3000;
const server = http.createServer((req, res) =>
if (req.url == '/')
res.writeHead(200, 'Content-Type': 'text/html' );
res.write('<html><body>Hello, node.js!</body></html>');
res.end();
else
res.writeHead(404);
res.end();
);
server.listen(PORT);
console.log(`Server started, port $PORT`);
当我们在Windows端修改了该文件,nodemon会自动检测到文件改变,然后自动重新启动
现在访问不存在的路径会自动返回404
注:自动启动功能在Windows10上结合docker desktop,并没有测试成功,仍需手动重启,可能有一些兼容性原因; 一个StackOverflow上的解决方法是用nodemon --legacy-watch index.js启动,--legacy-watch会将nodemon听(listen)文件系统事件的行为变成轮询(poll),这样理论上会慢一点,但可以保证能够检测到文件的改变并自动重启
6、一个更好的index.js
'use strict';
const http = require('http');
const PORT = 3000;
const server = http.createServer((req, res) =>
let respBody = '';
let contentType = 'text/html';
let httpCode = 404;
try
switch (req.method.toLowerCase())
case 'get':
// can add logs to see elements
console.error(req.url)
const urlPath = req.url.split('/');
if (req.url === '/')
httpCode = 200;
respBody = 'Welcome home';
else if (urlPath.length === 2 && urlPath[1] === 'greet')
httpCode = 200;
respBody = '<html><body>Hello, node.js!</body></html>';
else if (urlPath.length === 3 && urlPath[1] === 'greet' && urlPath[2].match(/^a-z+$/))
httpCode = 200;
respBody = `<html><body>Hello $urlPath[2], node.js!</body></html>`;
break;
case 'post':
// add me
break;
catch (err)
respBody = `Error: $err.message`;
httpCode = 500;
res.writeHead(httpCode, 'Content-Type': contentType );
res.write(respBody);
res.end();
);
server.listen(PORT);
console.log(`Server started, port $PORT`);
调试,-v可以输出完整的接受到的包信息
curl -v http://127.0.0.1:3000/greet
7、一个神奇的报错
[nodemon] app crashed - waiting for file changes before starting...
其实是因为我的js里有个语法错误,一个括号没有闭合而已,和文件有没有改变没有关系
8、使用url包,自动解析url,更易于应对更加复杂的url
'use strict';
const http = require('http');
const PORT = 3000;
// const qs = require('querystring');
const url = require('url');
const server = http.createServer((req, res) =>
let respBody = '';
let contentType = 'text/html';
let httpCode = 404;
console.error(req.url)
const reqUrl = url.parse(req.url, true);
console.error(reqUrl)
const urlPath = reqUrl.pathname.split('/');
console.error(urlPath)
if (urlPath.length === 2 && urlPath[1] === 'greet')
httpCode = 200;
respBody = reqUrl.query.name ? `<html><body>Hello $reqUrl.query.name, node.js!</body></html>` :
'<html><body>Hello, node.js!</body></html>';
else
res.writeHead(httpCode, 'Content-Type': contentType );
res.write(respBody);
res.end();
)
server.listen(PORT);
// 这行代码将被执行,因为js的异步机制,而在python中则不会执行到这
console.log(`Server started, port $PORT`);
9、express中间件
我猜测express是基于html包做了封装,或者实现了类似html包的功能,也能提供服务,监听端口,并进行路由,以及其他更强大的功能
安装express,因为不需要在terminal使用,因此不用加-g(globally),直接locally安装即可
npm install express
index.js文件
'use strict';
const express = require('express');
const app = express();
app.get('/greet', (req, res) =>
res.writeHead(200, 'Content-Type': 'text/html' );
res.write('<html><body>Hello, express!</body></html>');
res.end();
);
app.listen(3000);
可见这里我们没有处理除了/greet以外的路径,但express会自动处理此问题,返回404,不会像html包那样需要自己处理
10、静态内容
创建public文件夹,放入index.html
<html>
<body>
<p>
Hello, static page!
</p>
</body>
</html>
在index.js添加app.use那一句
'use strict';
const express = require('express');
const app = express();
app.use(express.static('public'));
app.get('/greet', (req, res) =>
res.writeHead(200, 'Content-Type': 'text/html' );
res.write('<html><body>Hello, express!</body></html>');
res.end();
);
app.listen(3000);
此时访问直接访问http://127.0.0.1:3000时就不会报错,会自动返回该index.html
添加图片:在public下创建image文件夹,并添加一张图
在index.html中使用
<html>
<body>
<p>
Hello, static page!
</p>
<div id="mascot">
<a href="https://www.google.com/search?q=silly+cats">
<img src="/image/deeplearning.jpg" />
</a>
</div>
</body>
</html>
11、url传参
'use strict';
const express = require('express');
const app = express();
app.use(express.static('public'));
app.get('/greet', (req, res) =>
res.writeHead(200, 'Content-Type': 'text/html' );
res.write(`<html><body>Hello, $req.query.first_name $req.query.last_name</body></html>`);
res.end();
);
app.get('/greet/:firstName/:lastName', (req, res) =>
res.writeHead(200, 'Content-Type': 'text/html' );
res.write(`<html><body>Hello, $req.params.firstName $req.params.lastName</body></html>`);
res.end();
);
app.listen(3000);
比如
http://127.0.0.1:3000/greet?first_name=1&last_name=xixi
得到Hello, 1 xixi
http://127.0.0.1:3000/greet/xixi/haha
得到Hello, xixi haha
12、npm install express-list-endpoints
查看定义的路由
index.js
'use strict';
const express = require('express');
const listEndpoints = require('express-list-endpoints');
const app = express();
console.log(listEndpoints(app));
app.use(express.static('public'));
app.get('/greet', (req, res) =>
res.writeHead(200, 'Content-Type': 'text/html' );
res.write(`<html><body>Hello, $req.query.first_name $req.query.last_name</body></html>`);
res.end();
);
app.get('/greet/:firstName/:lastName', (req, res) =>
res.writeHead(200, 'Content-Type': 'text/html' );
res.write(`<html><body>Hello, $req.params.firstName $req.params.lastName</body></html>`);
res.end();
);
console.log(listEndpoints(app));
app.listen(3000);
得到结果,可见定义后输出了我们定义的路由
[ path: '', methods: [], middlewares: [] ]
[
path: '/greet', methods: [ 'GET' ], middlewares: [ 'anonymous' ] ,
path: '/greet/:firstName/:lastName',
methods: [ 'GET' ],
middlewares: [ 'anonymous' ]
]
13、uuid
一个debug小技巧,用nodemon启动index.js如果有bug很难看出问题,而换成node启动则会直接报错提示,便于调试
安装uuid
npm install uuid
index.js文件
'use strict';
const uuid = require('uuid');
const express = require('express');
const app = express();
app.use(express.static('public'));
app.get('/greet', (req, res) =>
req.my_data =
start_at: new Date(),
request_id: uuid.v4()
;
console.log(`Request complete -- path:$req.path, status:$res.statusCode, id:$req.my_data.request_id`)
res.writeHead(200, 'Content-Type': 'text/html' );
res.write(`<html><body>Hello, $req.query.first_name $req.query.last_name</body></html>`);
res.end();
);
app.listen(3000);
也可以把greet中的语句分开写,但需要加入next(),不然不会执行下一个greet,而是直接结束该函数的执行
'use strict';
const uuid = require('uuid');
const express = require('express');
const app = express();
app.use(express.static('public'));
app.get('/greet', (req, res, next) =>
req.my_data =
start_at: new Date(),
request_id: uuid.v4()
;
next();
);
app.get('/greet', (req, res, next) =>
console.log(`Request complete -- path:$req.path, status:$res.statusCode, id:$req.my_data.request_id`)
next();
);
app.get('/greet', (req, res, next) =>
res.writeHead(200, 'Content-Type': 'text/html' );
res.关于在k8s-desktop-for-mac如何坚持优雅地填坑
访问docker desktop创建的Hyper-v虚拟机DockerDesktopVM
Docker zookeeper 集群 for Docker desktop (win)
Docker Desktop 可以直接启用Kubernetes 1.25 了