特指不用来作为程序运行环境,而是单纯执行一些自定义命令。

例如当你想在宿主机新建一个 node 项目,需要使用 npm init 来自动生成 package.json 项目结构,但 npm 并非 linux/windows 自带的工具,且安装它需要具有完整的 node.js 环境。而 Docker 哲学就是所有的东西都不会装在宿主机上,因此就衍生出一个专门用于运行像 npm 这样的工具的工具箱容器。

这就需要 docker exec 命令,可以在 node 容器中运行。或者使用 docker run 来在运行 node 容器时覆盖其默认操作为传入的指令(在dockerfile中的CMD配置项)。

这里先创建一个 node:14-alpine 即 node 的轻量版本用于 node 工具箱容器:

FROM node:14-alpine
 
WORKDIR /app

并运行:

docker build -t node-util .

在这之后就可以通过 docker run 来执行 npm 命令:

docker run -it --rm -v <yourFilePath>:/app node-util npm init

和在宿主机环境安装 npm 并进行 init 的效果一样。

除此之外,也可以通过 ENTRYPOINT 来设置默认要执行的命令前缀,因为 CMD 命令会被手动替代而 ENTRYPOINT 不会:

FROM node:14-alpine
 
WORKDIR /app
 
ENTRYPOINT [ "npm" ]

此时就相当于 docker run -it --rm node-util init = npm init

docker run -it --rm -v <yourFilePath>:/app node-util init

使用 docker-compose

而每次都使用这种很长的路径相当麻烦,故可以通过 docker-compose 来简化,首先新建一个yaml:

version:'3.8'
services:
  npm:
    build: ./
    stdin_open: true
    tty: true
    volumes:
      - ./:/app

之后就可以使用 docker-compose run npm 来运行:

docker-compose run --rm npm init

其中若使用 compose up 则只是运行了 npm ENTRYPOINT,若想添加自己自定义的命令还需要使用 docker-compose run,不过这样就不会在容器运行结束时自动删除容器,得再加个 --rm 参数。