使用 Docker 部暑Node.js应用

 2017年03月16日    1345     声明


本篇我们将使用Docker部暑更复杂的应用,在本文示例中,我们会创建一个简单的名为express-app的Node.js(Express)应用,并通过Dockerfile构建镜像,实现基于Docker的Node.js应用的快速部暑。

  1. 创建express-app应用
  2. 初始化Dockerfile
  3. 构建镜像
  4. 运行容器
  5. 异地部暑应用

1. 创建express-app应用

使用以下命令创建在本例中所使用Web应用express-app

$ express -e express-app

命令执行完后,会在当前工作目录下生成一个express-app目录,也就是这个示例中所使用的Express应用:

$ ls
express-app

同时,express-app目录也是当前示例的工作目录,我们会在这个目录中创建Dockerfile、构建镜像等。进入工作目录,继续后续操作:

$ cd express-app

注意:创建应用前请确保己安装Node.js及Express环境,创建Express应用并在本文介绍范围。更多关于创建Express应用的介绍请参考:


2. 初始化Dockerfile

接下来,我们会通过Dockerfile文件来实现Docker镜像的构建。

创建编辑Dockerfile文件:

$ touch Dockerfile
$ vi Dockerfile

Dockerfile文件内容如下:

# Express-App
#
# VERSION  1.0.0

FROM node:latest

RUN mkdir -p /home/www/express-app
WORKDIR /home/www/express-app

COPY . /home/www/express-app
RUN npm install

EXPOSE 3000
CMD ["npm", "start"]

在这个文件包含了以下命令:

  1. FROM node:latest - 指定使用最新版本的node(当前为7.7.1)基础镜像
  2. RUN mkdir -p /home/www/express-app - 在容器内创建/home/www/express-app目录
  3. WORKDIR /home/www/express-app - 将容器内工作目录设置为/home/www/express-app
  4. COPY . /home/www/express-app - 将宿主机当前目录下内容复制到镜像/home/www/express-app目录下
  5. RUN npm install - npm install安装应用所需的NPM
  6. EXPOSE 3000 - 对外开放容器的3000端口
  7. CMD ["npm", "start"] - 在容器启动时,执行npm start命令启动应用


3. 构建镜像

编写完Dockerfile文件后,就可以通过docker build命令来构建镜像:

$ sudo docker build -t itbilu/express-app .

如上所示,我们通过-t参数,将镜像命名为itbilu/express-app。构建过程类似如下:

Sending build context to Docker daemon  16.9 kB
Step 1/7 : FROM node:latest
7: Pulling from library/node
693502eb7dfb: Pull complete 
...
Digest: sha256:a819cbe91f5cec9ade30bddbffa39d742c41159416deab7c492eb219cdf0e55f
Status: Downloaded newer image for node:latest
 ---> 607ddfc64bef
Step 2/7 : RUN mkdir -p /home/www/express-app
 ---> Running in fd4530f89cd1
 ---> ef1f14d62ceb
Removing intermediate container fd4530f89cd1
Step 3/7 : WORKDIR /home/www/express-app
 ---> 7e81460c9cc6
Removing intermediate container d16636d05c40
Step 4/7 : COPY . /home/www/express-app
 ---> e95b0b9d693c
Removing intermediate container 8f78d3234884
Step 5/7 : RUN npm install
 ---> Running in 9ce47f8a73de
npm info it worked if it ends with ok
npm info using npm@4.1.2
npm info using node@v7.7.1
npm info attempt registry request try #1 at 8:01:20 AM
...
app@0.0.0 /home/www/express-app
+-- body-parser@1.15.2 
...
`-- serve-favicon@2.3.2 
  `-- ms@0.7.2 

npm info ok 
 ---> f476ea375002
Removing intermediate container 9ce47f8a73de
Step 6/7 : EXPOSE 3000
 ---> Running in 3f6ed82cb5b6
 ---> 3d6bf0c0a61a
Removing intermediate container 3f6ed82cb5b6
Step 7/7 : CMD npm start
 ---> Running in ddc1f562c1fc
 ---> c70be2c84bef
Removing intermediate container ddc1f562c1fc
Successfully built c70be2c84bef

从上面构建过程可以看到,生成最终镜像共7步,每一步都对应一个Dockerfile中的命令。在构建过程中,每步都会自动提交一次,并生成一个中间镜像。

可以通过docker history查看这个镜像的构建过程:

$ sudo docker history itbilu/express-app


4. 运行容器

镜像构建完成后,可以通过所构建的镜像创建/运行容器,从而实现express-app应用的 Docker 化部暑。

使用itbilu/express-app镜像运行一个容器:

$ sudo docker run -d --name experss-app -p 3000:3000 itbilu/express-app

在以上操作中,我们通过itbilu/express-app镜像运行了容器,并将容器命名为experss-app。运行容器,我们还指定了-d参数,该参数使容器以后台的方式运行。而-p参数将宿主机的3000端口映射到了容器的3000端口。

运行容器后,可以通过docker ps命令看到运行中的容器:

$ sudo docker ps
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                    NAMES
6c11f05f161c        itbilu/express-app   "npm start"         About an hour ago   Up About an hour    0.0.0.0:3000->3000/tcp   experss-app

然后,就可以在宿主机的浏览器输入http://127.0.0.1:3000http://127.0.0.1:3000查看运行效果:

Docker部暑Node.js应用

5. 异地部暑应用

目前为止,我们已经完成了应用镜像的构建,并基于新构建的镜像在宿主机上运行了容器。但这并不能满足我们的需求,在实际应用中,我们不仅还需要在生产环境运行容器,以实现应用的部暑。要异地部暑应用,可以通过以下两种方式实现:

  1. 基于镜像部暑应用
  2. 基于Dockerfile部暑应用

5.1 基于镜像部暑应用

在前面的操作过程,我们通过Dockerfile文件在本地构建了itbilu/express-app镜像。要想在异地使用这个镜像,可以将这个镜像推送到Registry中,然后就可以在异地使用这个镜像。

镜像推送到Registry

可以通过docker push命令将itbilu/express-app推送到Docker Hub中:

$ sudo docker push itbilu/express-app

命令执行完成后,会在Registry(即:Docker Hub)中创建itbilu/express-app镜像仓库。

注意:推送镜像前,请确保已经通过docker login登录过Docker Hub

部暑应用

镜像提交后,就可以在需要部暑应用的地方通过docker pull拉取镜像后,再使用docker run运行容器。也可以使用docker run直接指定itbilu/express-app镜像名来运行容器。

以下是在一台远程的,CentOS 7发行版系统上的通过itbilu/express-app镜像部暑应用的示例:

使用docker run运行容器时,由于本地不存在所使用的镜像,因此,Docker首先会去Registry中查找并下载镜像。


5.2 基于Dockerfile部暑应用

除了可以基于已构建的镜像部暑应用来,还可以下载Dockerfile文件后构建镜像,然后再通过构建的镜像来运行容器,实现应用的部暑。

如,前面示例的experss-app应用已上传到了GitHub。这样就可以在所需要部暑应用的地方,下载Dockerfile及应用代码后构建镜像,然后通过所构建镜像运行容器。

https://github.com/itbilu/demo-docker-express-app

以下是一个在Ubuntu 16.04系统中,通过Dockerfile构建镜像并部暑应用的过程:

下载Dockerfile及应用代码:

$ git clone git@github.com:itbilu/demo-docker-express-app.git express-app

进入目录,构建镜像:

$ cd express-app
$ sudo docker build -t express-app .

构建完成后,会在宿主机生成一个express-app镜像,然后就可以通过这个镜像创建并运行容器:

$ sudo docker run -d --name express-app -p 80:3000 express-app
f5603004600ce2049662c57ba703dc2d63af815cfac19406308ea9d00e46fb2d