Skip to main content

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容器列表。 Locale Dropdown
如果使用vscode进行日常开发,推荐安装docker插件,当编写DockerFile时,它可以智能的链接到远程注册表:
Locale Dropdown

编写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的时候,当鼠标移动到关键词上,会有其解释或可跳转到对应的地址: Locale Dropdown
接下来逐个检视上述DockerFile中指令的作用:

  • Form:基础镜像,即将要构建的镜像是基于,node.js v12
  • WORKDIR:工作目录
  • 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即可在浏览器中看到如下效果 Locale Dropdown

持久化容器数据

到目前为止,如果将容器关闭,那么它运行时产生的数据就是消失,这时候就需要用到卷,它用来存储我们的容器数据,使得多个容器之间也可以共享数据

运行如下命令创建卷:

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 服务。