实战容器编程好基友之visual studio code+docker篇(二):实时调试运行在docker中的node.js程序,dockernode.js
实战容器编程好基友之visual studio code+docker篇(二):实时调试运行在docker中的node.js程序,dockernode.js
上篇文章中,我们介绍了怎么利用visual studio code在本地编译生成docker镜像,这篇文章我们会介绍怎么利用Visual studio code 实时调试运行在容器中的node.js程序。
这里我们还会利用之前的项目node-todo, 环境搭建请参考上篇文章中的准备工作部分。
其实细心的同学会发现,在我们上篇文章中,通过vscode快捷命令添加dockerfile的时候,除了会添加dockerfile,docker-compose file还会添加一个docker-compose.debug.yml,这个是vscode添加的专门用来调试的compose文件,
让我们打开这个文件,就会看到如下配置:
version: '2'
services:
node-todo:
image: node-todo:latest
build:
context: .
dockerfile: dockerfile
environment:
NODE_ENV: development
MONGODB: {connectiongstring}
ports:
- 8080:8080
- 5858:5858
volumes:
- .:/usr/src/app
command: node --debug=5858 server.js
这里,我们会看到它多开了一个端口号5858,这个就是我们用来remotedebug的端口号。
另外volumes参数把本地当前程序文件夹的内容覆盖docker中的代码部署的路径
最后compose中的command会覆盖dockerfile中的command命令,通过debug=5858参数允许远程调试。这样确保我们生成的镜像是干净和一致的,因为我们不希望我们将镜像部署到产品环境的时候也打开调试端口。
另外让我们回过头来再看下vscode帮我们生成的dockerfile
FROM node:4.2.3
COPY package.json /tmp/package.json
RUN cd /tmp && npm install --production
RUN mkdir -p /usr/src/app && mv /tmp/node_modules /usr/src
WORKDIR /usr/src/app
COPY . /usr/src/app
EXPOSE 8080
CMD node server.js
这里有两点
1. 我们修改基础的node 镜像标签用一个固定的版本号如4.2.3,这样明确指定tag的好处是我们生成的镜像总是一致的,避免因为dockerhub中镜像升级,导致我们引入不同的基础镜像,造成生成镜像的不一致。
2. 细心的同学会发现这段命令
RUN cd /tmp && npm install–production
RUN mkdir -p /usr/src/app && mv/tmp/node_modules /usr/src
它在tmp文件夹中通过npm安装依赖,然后生成了一个文件路径/usr/src/app,下面用通过copy命令放置我们的程序代码。但是有意思的是它把依赖node_modules,放置到了/usr/src里面,也就是说它把依赖放在程序文件夹的父文件夹中,而不是程序文件夹里面。我们知道若没有在require中指定路径,nodejs 会在当前程序的父文件夹中寻找node_modules文件。例如我们在/usr/src/app/server.js中通过require(‘express’)引用了express,那么在启动server.js时候,node.js总是会首先到/usr/src/app/node_modules, 然后去/usr/src/node_modules寻找依赖,并依次向上。那为什么模版不把依赖放在/usr/src/app/里面呢?这是因为我们在远程调试的时候会将本地的代码覆盖docker中程序文件夹。如果依赖放在/usr/src/app/中,在远程调试就会被本地代码覆盖,所以这里把依赖放在了上级目录里面。由此我们可以看到,我们要确保在/usr/src/app不包含node_modules,这样它就可以到上级目录寻找正确的依赖,这就要求我们
在生成镜像的时候,本地程序文件夹中不包含依赖。
在我们远程调试的时候mount本地程序文件夹到docker里面的路径的时候,本地程序文件夹中也没有node_module
这样就避免了我们本机是mac/windows环境下载的依赖包,覆盖了基于linux环境的docker中的依赖,带来一些跨平台的问题。
最后让我们来配置这个项目的调试环境.看项目文件中,如果没有/.vscode/launch.json,则直接按F5,选择node.js,然后自动创建/.vscode/launch.json文件,修改如下
{
// Use IntelliSense to learn about possible Node.js debug attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceRoot}/server.js",
"cwd": "${workspaceRoot}",
"restart": false
},
{
"type": "node",
"request": "attach",
"name": "Attach to Process",
"port": 5858,
"address":"localhost",
"localRoot": "${workspaceRoot}/",
"remoteRoot":"/usr/src/app/",
"restart": true
}
]
}
这里有两部分,一部分是launchprogram主要是在本机调试的时候用到,另外一部分是Attachto Process 是在在远程编译的时候用到,今天我们主要介绍attach部分,这里要注意几个配置
· Port,指定了调试的端口号,与项目启动后监听的端口号是不同的
· Address,用来指定调试的远程主机的地址,如果docker 跑在本机可以用localhost,如果不是请用命令docker-machieip {机器名}获取及其的ip地址后替换
· LocalRoot,用来指定本地代码的地址,这里我们用参数{workspaceRoot}用来指向当前vscode打开的路径。
· remoteRoot 远程主机或者容器中代码运行的地址。
· restart, 指定当nodejs重启时是否重新启动debug,这个在后面会用到
在这些都配置好以后我们就可以开始调试了。
首先通过shift+ command + P启动快捷命令窗口,输入docker: compose up, 选择docker-compose.debug.yml文件,然后我们会看到在terminial中的输出
我们会看到程序端口和调试端口都已经在监听。让我们在route.js中打一个断点,
然后打开vscode的调试页面,选择attachto process ,
按下f5,然后,然后用浏览器打开http://localhost:8080,如果发现代码已经停留在我们的断点处了,那么恭喜你已经可以开始远程调试docker里面的程序了。
但是还有一个问题,就是如果我们修改了本地的代码,例如我们将页面的标题改为“Thisis a test”,刷新页面发现我们的改动并没有生效。难道我们在调试的时候每次改动都要重新生成一遍镜像吗?这样太麻烦了。这里我们就需要引入一个工具nodemon,它会自动监视文件夹里面的改动,然后重启进程,具体改动如下:
1. 在docker file文件中添加以下命令在全局安装nodemon
RUN npm install -g nodemon
2. 在docker-compose.debug.yml文件中,将CMD中node启动改为nodemon启动,例如
command: nodemon --debug=5858 server.js
好的,把我们之前生成的docker通过命令docker rm –f $(docker ps -aq)删除,重新通过快捷命令窗口启动docker:compose up.这时我们在terminial中,会看到nodemon已经开始监控文件变化
这时我们再按f5就可以开始愉快的调试,修改保存后,nodemon会重启nodejs进程,修改实时生效。还记得我们在vscode的launch.json中将attach部分的restart设成了true吗?当nodemon重启进程后,vscode也会重启debugger重新attach,这样就可以继续调试了
以上是我基于macos做的设置,对于使用windows作为开发平台的同学,需要额外做两件事
1. 在docker 的设置里面要将放置代码的磁盘共享,这样就可以将本地代码mount到docker里面
2. 在compose文件中nodemon 启动命令时添加一个-L参数
command: nodemon --debug=5858 -L server.js
好的今天就介绍到这里,大家在用vscode过程中有任何问题可以到github上https://github.com/Microsoft/vscode 和大家交流,Erich Gamma大神也经常在上面直接回答问题。
相关文章
- 暂无相关文章
用户点评