docker入门
使用docker将node.js应用容器化,来展示如何使用docker
什么是docker
docker是一种打包方式,通过docker打包的引用可以运行在任何操作系统或硬件上。
要知道docker是如何工作的,需要知道三个东西,分别是DockerFile、Image、Container;
- DockerFile 用于构建Docker Image
- Docker Image是运行应用的模板
- Container是正在运行的进程实例
在接下的示例用,Node.js应用是运行在一个具有特定Node.js版本的服务器中,并且安装了相应的依赖,但是如果想要在其它机器访问,很难保证一致的nodejs版本,docker通过复制nodejs应用的环境来解决这类问题。
使用DockerFile定义开发环境,然后任何开发人员就可以通过DockerFile构建出具有相同环境的不可变镜像,可以将镜像上传到云或自己的服务器,其他开发人员将镜像拉到本地并运行一个容器来运行node.js应用。
安装docker
打开docker官网,选择下载对应平台的docker桌面应用,它提供了GUI和命令行,推荐安装,如下是安装好的docker,很方便的查看正在运行的容器,在终端输入docker ps可以查看当前正在运行的docker容器列表。

如果使用vscode进行日常开发,推荐安装docker插件,当编写DockerFile时,它可以智能的链接到远程注册表:
编写DockerFile
首先需要准备一个简单的node.js应用,案例中使用的是express。
新建nodejs-with-docker目录、index.js,在终端执行:
yarn init -y
yarn add express -D
编写index.js
const app = require('express')();
app.get('/', (req, res) => {
res.json({ message: 'Docker is easy!' });
});
const port = process.env.PORT || 8080;
app.listen(port, () => console.log(`app listening on http//localhost:${port}`));
在package.json加入如下代码:
{
"scripts": {
"start": "node index.js"
}
}
现在已经准备了一个node.js应用,当执行yarn start时,默认监听了8080端口,当访问根路由时,会返回一个json格式的数据。
新建DockerFile,内容如下:
FROM node:12
WORKDIR /app
COPY package.json ./
COPY yarn.lock ./
RUN yarn
COPY . .
ENV PORT=8080
EXPOSE 8080
CMD ["yarn", "start"]
由于安装了docker插件,在编辑DockerFile的时候,当鼠标移动到关键词上,会有其解释或可跳转到对应的地址:

接下来逐个检视上述DockerFile中指令的作用:
Form:基础镜像,即将要构建的镜像是基于,node.js v12WORKDIR:工作目录COPY:将源文件复制到目标路径中,为了能够缓存安装的依赖,将package.json和yarn.lock都复制到工作目录,这样就不必每次都重新安装;COPY...将当前项目所有文件都复制到docker的工作目录,但是需要忽略node_module,新建.dockerignore,写入node_modules,这样镜像中就有了源代码。RUN:执行shell命令,这里使用了yarn安装依赖。ENV:设置环境变量EXPOSE:定义docker容器在运行时监听的端口CMD:告诉docker如何启动应用,它不会启动一个shell session,也就是说当终端退出,该应用任然在运行中。
构建镜像
有了DockerFile,就可以构建镜像了:
docker build -t yehoo/demoapp:1.0 .
- -t后面跟的是镜像名称,这个可以自己自定义,建议使用DockerHub的用户名为开头,然后是斜杠加镜像名,后面跟
:1.0表示的是版本号。 - 最后一个
.表示的使用当前路径下的DockerFile进行构建镜像。
运行容器
构建完镜像后可以拿到镜像ID,然后执行以下命令运行容器:
docker run 587d4f94eeca
运行成功后,箭筒的8080端口是在容器内可访问,但是作为宿主机仍无法访问,所以要定义宿主机和docker容器端口的映射关系:
docker run -p 8080:8080 587d4f94eeca
运行成功后,打开http://localhost:8080即可在浏览器中看到如下效果
持久化容器数据
到目前为止,如果将容器关闭,那么它运行时产生的数据就是消失,这时候就需要用到卷,它用来存储我们的容器数据,使得多个容器之间也可以共享数据
运行如下命令创建卷:
docker volume create shared-stuff
Docker Compose
通常一个容器对应一个进程,使用 docker compose 可以同时运行多个不同的容器
新建 docker-compose.yml,代码如下:
version: '3'
services:
web:
build: .
ports:
- '8080:8080'
db:
image: 'mysql'
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- db-data:/foo
执行 docker-compose up,如果运行成功,则同时运行了两个容器,一个是 node.js 应用,一个是 mysql 服务。