使用Docker设置本地Node.js开发环境

VS Code 提供了 Docker Atlas 扩展可以方便build,管理和部署容器化应用。由于VSC可以跨平台,在 macOS / Windows AtlasLinux Atlas 都能一致性地使用,非常适合开发轻量级应用,特别是 JavaScript Atlas ( Node.js Atlas )

备注

我的开发环境在 Apple ARM架构芯片M1 Pro 处理器的MacBook Pro上,所以安装 Docker Desktop 来运行容器环境。在 Linux Atlas 平台可以直接运行 Docker AtlasKubernetes Atlas 来构建 移动云架构

安装

../../_images/vscode_docker_extension.png

创建Express Node.js应用

在项目中添加Docker文件

  • VS Code 中打开 demo 项目目录

  • 打开命令面板 ( ⇧⌘P ) ,然后使用 Docker: Add Docker Files to Workspace... 命令,根据提示依次回车(默认值)

    • 对于application platform,选择 Node.js

    • 对于是否包括 Docker Compose 文件(类似 Kubernetes Atlas 的pod,可以同时运行多个容器)

    • 应用端口保持默认 3000

此时 VS Code 会自动创建如下 Dockerfile 以及一个 .dockerignore 文件:

FROM node:lts-alpine
ENV NODE_ENV=production
WORKDIR /usr/src/app
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
RUN npm install --production --silent && mv node_modules ../
COPY . .
EXPOSE 3000
RUN chown -R node /usr/src/app
USER node
CMD ["npm", "start"]

如果选择了包含 Docker Compose 文件,则会同时生成 docker-compose.ymldocker-compose.debug.yml 。最后, VS Code 的 Docker扩展还会在 .vscode/tasks.json 中创建一系列VS Code任务用来build和run容器

在镜像中添加环境变量

VS Code 的Docker扩展是通过IntelliSense来首先自动完成和上下问帮助的,要激活这个功能,需要在服务镜像中添加一个环境变量:

  • 打开 Dockerfile 文件

  • 在服务镜像中添加 ENV 变量,例如 ENV VAR1=1 (现在没有什么意义,后面再根据实际需要传递的环境变量配置,例如配置数据库连接账号等等)

  • 保存 Dockerfile 文件

在本地运行服务

  • VS Code 中打开一个终端

  • 执行 npm run start 命令

  • 使用浏览器访问 http://localhost:3000 就能够看到一个简单Express欢迎页面

../../_images/node-run-browser.png

验证成功后,在终端中按下 ctrl-c 终止node.js服务,此时在浏览器中已经无法访问页面

构建服务镜像

  • VS Code 中打开命令行面板( ⇧⌘P ),然后选择 Docker Images: Build Image... 命令,此时 VS Code 就会根据前面的 Dockerfile 构建镜像

  • VS Code 左方的 Docker Explorer 中(点击那个著名的 鲸鱼背负集装箱 图标),验证是否正确生成镜像:

../../_images/vscode_docker_image.png

运行服务镜像

  • 右击build好的镜像,然后选择 Run (也可以选择 Run Interactive ) 此时可以看到终端运行命令:

    docker run --rm -d  -p 3000:3000/tcp demo:latest
    
  • 现在再次打开浏览器访问 http://localhost:3000 又可以看到Express欢迎页面了,只不过这次不是在主机本地运行的node.js服务,而是在容器内部运行的服务

  • 验证成功后,在vscode的Container导航树中,右击正在运行的容器 demo ,点击 Stop 停止容器

../../_images/vscode_docker_stop_container.png

在服务容器中Debug

当Docker扩展向应用程序添加文件时,会同时在 .vscode/launch.json 添加一个VS Code调试器配置,用于在容器内运行时调试服务。扩展检测服务使用的协议和端口,并将浏览器指向服务:

{
    "configurations": [
        {
            "name": "Docker Node.js Launch",
            "type": "docker",
            "request": "launch",
            "preLaunchTask": "docker-run: debug",
            "platform": "node"
        }
    ]
}
  • 在Express应用 routes/index.js 文件中找到 处理 '/''get() ,在这行代码行号左方点一下,增加一个断点 (breakpoint)

../../_images/vscode_breakpoint.png
  • 确保 launch.json 中已经配置了 debug ,见上文:

    ...
                "preLaunchTask": "docker-run: debug",
    ...
    
  • 按下 F5 开始debugging

此时在 Terminal 终端会看到运行了如下 Docker 命令:

docker run -dt -P --name "demo-dev" -e "DEBUG=*" -e "NODE_ENV=development" --label "com.microsoft.created-by=visual-studio-code" -p "9229:9229" "demo:latest" node --inspect=0.0.0.0:9229 ./bin/www

整个过程分为如下几步:

  • 服务构建了Docker镜像

  • Docker容器中运行服务

  • 浏览器打开了映射到服务容器的(随机的)端口

  • debugger停止在 index.js 的断点位置

备注

由于debugger是在应用启动以后附加上去的,这个断点有可能错过了首次运行,可能需要刷新浏览器才能在第二次重试中看到调试器中断。

观察应用日志

VS Code 中可以使用容器的 View Logs 命令观察日志:

  • Docker Explorer 中,选中正在运行的debugging容器,右击选择菜单 View Logs ,就能在 TERMINAL 中看到容器输入日志(其实就是 docker attach 到容器控制台观察日志)

../../_images/vscode_nodejs_debug_logs.png

参考