codecamp

vscode 支持Docker

今天我们要介绍的内容是,如何在 VS Code 中配置、部署和调试 Docker。

在阅读本文之前,首先你需要对 Docker 容器化的知识有所了解。其次,Docker 的操作,都可以通过命令行来实现。所以今天我要着重介绍的就是:VS Code里如何使用 UI 和命令来简化命令行操作,以及如何对 Docker 容器里的代码进行调试,这里我会借助两个简单的例子来讲解。

安装Docker插件

VS Code 的 Docker 支持,是由插件来完成的,这个插件是 VS Code 官方团队维护的,所以它的发布者是 Microsoft。你可以在市场上点击下载,也可以直接在 VS Code 插件视图里搜索 Docker 进行安装。

当然了,这个插件的正确运行,离不开一个正确安装的 Docker 环境。关于 Docker 的安装,还请参考官方文档


安装完Docker插件后,在活动栏上,我们就能够看到一个集装箱的图标,点击它,我们就能够看到 Docker 相关的信息了。


在这个视图中,我们能够看到以下信息:

  • 当前环境中所有的 image;
  • 当前环境中存在的 container;
  • 以及 Docker 的仓库列表。

当我们在 image 上右击时,能够看到一系列的操作,比如查看 image 的信息、发布这个 image、运行 image 等。当然,这些操作同样也可以在命令面板中找到。


我们在 containers 上右击调出的上下文菜单就要简单一些,有三个命令:删除 container、重启 container以及查看这个 container 运行的日志。


Dockerfile

除了提供了一个视图,Docker 插件还能够对 Dockerfile 文件进行语法高亮。


而且也支持自动补全,这样我们就可以通过建议列表来输入 Dockerfile 中的命令了。

构建和运行

在书写了正确的 Dockerfile 之后,我们就可以通过这个 Dockerfile 来构建 image 了。为了方便理解,下面我们创建一个新的文件夹,在其中创建一个 Dockerfile。内容如下:

FROM alpine:latest

RUN apk --no-cache add \
    htop

CMD [ "htop" ]

这段 Dockerfile 的意思是,我们希望基于 alpine 系统,安装 htop 这个包,最后运行一个命令 htop,查看当前运行的各种进程。

docker build

接下来,我们就可以打开命令面板,执行 “Docker: Build image” 命令。这个命令会打开集成终端,然后执行 docker build 命令。

docker run

生成了 image 之后,我们就可以通过这个 image 来创建 container 了。此时,我们可以通过 Docker 视图的上下文菜单来生成“运行 container”,也可以从命令面板中,运行 “Docker: Run” 命令。然后 VS Code 就会询问我们想要使用哪个 image。

docker run interactive

除了 Run 这个命令外,另一个非常有用的命令就是 Run Interactive。通过这个命令,我们可以创建并运行 container,然后进入到这个 container 的 shell 环境汇总。

在上面的例子里,我们在 container 里运行的命令是 htop,也就是实时监控系统运行的情况;当我们执行了 “Run interactive” 命令,运行了 contaienr 并且进入到它的 shell 环境中后,我们就立刻看到了 htop 的运行界面。

看到这里你可能已经发现了:对于命令面板里执行每个命令,VS Code 都会打开集成终端,然后运行相对应 Docker 脚本。在你还在学习 Docker 的过程中,你可以先依赖于 VS Code 提供的命令,然后试着去理解 VS Code 每个命令背后的脚本的含义。

而下面这些就需要我们具备一定的 docker 命令行的知识。

输出 log

首先,我们对 Dockerfile 按如下稍作修改。

FROM alpine:latest
RUN apk --no-cache add \
    htop
CMD [ "pwd" ]

我们将Dockerfile中,最后一个配置 CMD 进行了修改。那么,从这个 image 生成的 container 运行起来后,会执行 pwd 命令,而非 htop 命令。

修改完 Dockerfile 之后,第一件要做的事情,就是重新构建 image。在构建这个 image 时,我们可以覆盖之前的那个 image,也可以重新起个名字来创建一个新的 image。比如我就给新的 image 取名为”vscode-docker-sample2:latest”。

有了新的 image 后,接下来就是从 “vscode-docker-sample2:latest” 创建一个新的 container。

在运行 docker run 的时候,如果你有留意左侧视图里 “containers” 这个列表的话,你会发现,一个名叫 vscode-docker-sample2 的 container 出现了一下然后又消失了。这是为什么呢?

我们来看一下集成终端,此时集成终端里运行的脚本是:

docker run --rm -d vscode-docker-sample2:latest

这行脚本中有一个参数 ‘–rm’,它的意思是:如果 container 里的命令执行结束的话,那就将这个 container 删除。由于这个 container 中运行的命令是 pwd,这个命令很快就结束了,所以我们来不及在视图中看到并且操作它。如果我们不希望这个 container 被删除该怎么办呢?

我们可以选择手动地运行如下的脚本:

docker run -d vscode-docker-sample2:latest

这一次,我们创建的 container 运行结束后就不会被删除了。也就是此时我们能够在左侧 Containers 列表里,看到 vscode-docker-sample2:latest (dreamy_…) 这个 container 了。它前面的图标里有一个红色的点,这说明这个 container 已经结束工作了。

我们可以在这个 container 上右击调出上下文菜单,选择 Show logs 命令。接着,我们就能够看到这个 container 中 pwd 命令执行的结果了,就是 ‘/’。

Docker Compose

除了 Dockerfile 的支持,Docker 插件还支持 Docker Compose。Docker Compose 是用于配置多个 container 并且将其同时运行的。和 Dockerfile 一样,我们一样也可以在 Docker compose file 里获得自动补全和错误检查。

这里,让我们用一个 Node.js 的代码示例,来展示 Docker Compose 以及接下来调试相关的内容。

首先,让我们将上文中创建的 Dockerfile 删除。然后在文件夹下创建一个 JavaScript 文件 index.js,内容如下:

function foo() {
    bar("Hello World");
}

function bar(str) {
    console.log(str);
}

foo();

JavaScript

(上面这段 JavaScript 代码,我们在专栏前面的内容里也经常使用,非常简单。)

接着,我们就需要为这个 JavaScript 代码准备 Docker 相关的配置了。不过值得庆幸的是,Docker 插件已经为我们提供了 Docker 配置的快捷生成方式了。

自动创建 Dockerfile 和 compose 配置

我们只需调出命令面板,然后搜索执行命令 “Docker: Add docker files to workspace”。

接着 VS Code 会问我们想要创建什么环境的 Docker image。这里我们选择 Node.js,这样就可以运行上面创建的 index.js 文件了。

命令执行后,工作区内多出了三个文件。第一个文件是Dockerfile。

FROM node:8.9-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

Shell

这个文件里,指定了 Node.js 8.9 作为基础 image,然后将当前工作目录下的 package.json 、package-lock.json 等都拷贝到 container 中去。接着运行 npm install 命令来安装代码运行所需的 dependencies。不过,由于我们只有一个简单的 JavaScript 文件,我们并不需要 npm,所以我们不妨把这个文件修改为:

FROM node:8.9-alpine
ENV NODE_ENV production
WORKDIR /usr/src/app
COPY . .
EXPOSE 3000

Shell

第二个文件是docker-compose.yml 。这个文件里指定了当前只有一个 container 需要被创建并运行,而且这个 container 需要使用端口 3000。

version: '2.1'

services:
  vscode-sample:
    image: vscode-sample
    build: .
    environment:
      NODE_ENV: production
    ports:
      - 3000:3000

第三个文件是docker-compose.debug.yml。顾名思义,它是用于调试时的 compose 文件,跟上面的 docker-compose.yml 文件相比,它只多了两行代码,也就是:

  • 9229:9229,使用 9229 端口;
  • command: node –inspect index.js ,在 container 运行起来后,运行 node 程序,并且调试 index.js 文件。
version: '2.1'

services:
  vscode-sample:
    image: vscode-sample
    build: .
    environment:
      NODE_ENV: development
    ports:
      - 3000:3000
      - 9229:9229
    ## set your startup file here
    command: node --inspect index.js

Compose Up

在有了这三个配置文件后,要想构建并且运行 container 就简单了。我们不再需要先执行 “Docker: build image ” 再运行 “Docker: run” 了,而是直接运行单个命令——“Docker: compose up” 即可。

运行 “Docker: compose up” 后,我们需要选择使用哪个 compose 配置文件。只要准备好了 compose 配置文件,那么在 VS Code 中操作就非常简单了,一共只有三个命令:

  • Docker compose up
  • Docker compose down
  • Docker compose start

如果你想看看 VS Code 是不是真的成功运行了 container,你可以从 Docker 的视图里,找到这个新创建出来的 container,查看它的 log。你能够看到以下结果:


index.js 在 container 里被成功地运行了,而且输出了 Hello World。

调试

我们在前面的文章里,做了这么多的准备工作,既创建了 JavaScript 文件,又使用了 Docker compose。不过这些操作,都是为调试内容做的准备。

这个 JSON 文件里的 configurations 的值就是当前文件夹下所有的配置了。现在我们只有一个调试配置,它有四个属性:第一个是 type,代表着调试器的类型。它决定了 VS Code 会使用哪个调试插件来调试代码。第二个是 request,代表着该如何启动调试器。如果我们的代码已经运行起来了,则可以将它的值设为 attach,那么我们则是使用调试器来调试这个已有的代码进程;而如果它的值是 launch,则意味着我们会使用调试器直接启动代码并且调试。……

当 request 的值被设置为 attach 后,我们就可以将调试器附着到已经处于调试状态的代码进程上了,接着我们就能够调试代码了。而调试 Docker 中的代码,就是使用的 attach 这个方法。我们可以在 Docker container 里以命令行的方式调试代码,并且开放调试端口,接着我们让 VS Code 里的调试插件附着到这个端口上即可。这就是在 VS Code 中调试非本地环境运行的代码的理论知识了。下面,我们一起看看怎么做。首先,我们对 docker-compose.debug.yml 做一点修改,将 command 改成如下的值:

command: node --inspect-brk=0.0.0.0:9229 index.js

这个命令是说,将调试 index.js 文件,然后在第一行停下来,并且使用 9229 这个端口进行调试。接着,让我们运行 “Docker: compose up” 将 container 运行起来。

下一步就是调试代码了。这里,我们使用的 .vscode/launch.json 文件内容如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "attach",
            "name": "Docker: Attach to Node",
            "port": 9229,
            "address": "localhost",
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "/usr/src/app",
            "protocol": "inspector"
        }
    ]
}

JSON

这个调试配置有几个属性值得注意:

  • request 是 attach,也就是附着到已经运行的代码上;
  • port 就是调试的端口;
  • localRoot 是本地代码的根目录;
  • remoteRoot 是指在远程运行的代码的根目录。在我们的例子里,我们已经在Dockerfile里指明了工作目录是 /usr/src/app (不记得的话还请翻上去看一看),所以此处我们输入 /usr/src/app。

有了这个调试配置后,F5 我们就能够调试 Docker container 中的代码了,并且停到了第一行代码上。到这里,我们就成功地将一段 JavaScript 代码运行在 Docker 中,并且从 VS Code 里调试起来了。


vscde 支持Emmet
vscode 固定UI视图
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }