使用 Docker Compose 对 Node.js 应用程序进行容器化开发

简介

如果您正在积极开发应用程序,使用Docker可以简化您的工作流程和将您的应用程序部署到生产中的过程。在开发中使用容器具有以下好处:

  • 环境是一致的,这意味着您可以为项目选择所需的语言和依赖项,而无需担心系统冲突。
  • 环境是隔离的,因此可以更轻松地排除故障并加入新的团队成员。
  • 环境是可移植的,允许您打包代码并与他人共享。

本教程将介绍如何使用Docker为Node.js应用程序)设置开发环境。您将使用Docker Compose)创建两个容器-一个用于节点应用程序,另一个用于MongoDB.数据库由于该应用程序可以与Node和MongoDB一起使用,因此您的设置将执行以下操作:

  • 将宿主机上的应用程序代码与容器中的代码同步,便于开发过程中的更改。
  • 确保对应用程序代码的更改无需重新启动即可生效。
  • 为应用程序数据创建受用户和密码保护的数据库。
  • 将此数据持久化。

在本教程结束时,您将拥有一个在Docker Containers上运行的鲨鱼信息应用程序:

完整鲨鱼收藏登陆page

前提条件

要遵循本教程,您需要:

  • 运行Ubuntu 18.04的开发服务器,以及具有sudo权限和活动防火墙的非超级用户。有关如何设置这些的指导,请参阅初始服务器设置guide.
  • 您的服务器上安装了Docker,遵循如何在Ubuntu 18.04.上安装和使用Docker》中的 步骤1和2**
  • Docker Compose安装在您的服务器上,按照如何在Ubuntu 18.04.上安装Docker Compose》中的 步骤1** 操作

第一步-克隆项目并修改依赖关系

构建此安装程序的第一步将是克隆项目代码并修改其package.json文件,该文件包含项目的依赖项。您将把nodemon添加到项目的devDependencies,中,指定您将在开发期间使用它。使用nodemon运行应用程序可以确保在您更改代码时自动重启应用程序。

首先,从DigitalOcean社区GitHub账号克隆[nodejs-mongo-mongoosehttps://github.com/do-community).该存储库包括如何将MongoDB与您的节点Application,集成》中描述的设置中的代码,其中解释了如何使用Mongoose.)将MongoDB数据库与现有的节点应用程序集成

将仓库克隆到名为node_project的目录下:

1git clone https://github.com/do-community/nodejs-mongo-mongoose.git node_project

导航到node_project目录:

1cd node_project

使用Nan或您喜欢的编辑器打开工程的Package.json文件:

1nano package.json

在项目依赖项下方和右大括号上方,创建一个新的devDependencies对象,其中包含nodemon

 1[label ~/node_project/package.json]
 2...
 3"dependencies": {
 4    "ejs": "^2.6.1",
 5    "express": "^4.16.4",
 6    "mongoose": "^5.4.10"
 7  },
 8  "devDependencies": {
 9    "nodemon": "^1.18.10"
10  }    
11}

编辑完成后,保存并关闭文件。如果您使用的是Nan,请按CTRL+X,然后按Y,然后按Enter

准备好项目代码并修改其依赖项后,您可以继续为容器化工作流重构代码。

Step 2 -配置应用使用容器

为容器化工作流修改应用程序意味着使代码更加模块化。容器提供了环境之间的可移植性,您的代码应该通过尽可能与底层操作系统解耦来反映这一点。为了实现这一点,您需要重构代码,以便更好地利用Node的process.env属性。这将返回一个对象,其中包含有关运行时用户环境的信息。可以在代码中使用此对象,以便在运行时通过环境变量动态分配配置信息。

从您的主应用程序入口点app.js开始。打开文件:

1nano app.js

在内部,您将看到一个[constant](https://andsky.com/tech/tutorials/understanding-variables-scope-hoisting-in-javascript#constants),‘端口的定义,以及一个使用此常量指定应用程序将侦听的端口的[function](https://expressjs.com/en/4x/api.html app.listen)’端口:

1[label ~/home/node_project/app.js]
2...
3const port = 8080;
4...
5app.listen(port, function () {
6  console.log('Example app listening on port 8080!');
7});

重新定义port常量,以允许在运行时使用cess.env对象进行动态分配。对常量定义和listen函数进行如下更改:

1[label ~/home/node_project/app.js]
2...
3const port = process.env.PORT || 8080;
4...
5app.listen(port, function () {
6  console.log(`Example app listening on ${port}!`);
7});

您的新常量定义使用运行时传入的值或8080动态分配port。类似地,您已经重写了literal](https://andsky.com/tech/tutorials/how-to-work-with-strings-in-javascript# string-literals-and-string-values),‘函数,以使用[模板listen,该模板将在侦听连接时插入端口值。由于您将在其他地方映射您的端口,因此这些修订将使您不必随着环境的变化而不断修订此文件。

编辑完成后,保存并关闭该文件。

接下来,您将修改数据库连接信息以删除所有配置凭据。打开db.js文件,其中包含以下信息:

1nano db.js

目前,该文件执行以下操作:

  • 导入Mongoose,即您用来为应用程序数据创建模式和模型的_Object Document Mapper_(ODM)。
  • 将数据库凭据设置为常量,包括用户名和密码。
  • 使用mongoose.Connectmethod.连接到数据库

关于文件的更多信息,请参考如何将mongodb与您的节点3集成]的步骤Application.

修改文件的第一步是重新定义包含敏感信息的常量。目前,这些常量如下所示:

1[label ~/node_project/db.js]
2...
3const MONGO_USERNAME = 'sammy';
4const MONGO_PASSWORD = 'your_password';
5const MONGO_HOSTNAME = '127.0.0.1';
6const MONGO_PORT = '27017';
7const MONGO_DB = 'sharkinfo';
8...

您可以使用cess.env对象来捕获这些常量的运行时值,而不是对这些信息进行硬编码。将块修改为如下所示:

 1[label ~/node_project/db.js]
 2...
 3const {
 4  MONGO_USERNAME,
 5  MONGO_PASSWORD,
 6  MONGO_HOSTNAME,
 7  MONGO_PORT,
 8  MONGO_DB
 9} = process.env;
10...

编辑完成后,保存并关闭文件。

此时,您已经修改了db.js以处理应用程序的环境变量,但您仍然需要一种方法将这些变量传递给您的应用程序。创建一个.env文件,其中的值可以在运行时传递给您的应用程序。

打开文件:

1nano .env

该文件将包括您从db.js中删除的信息:您的应用程序数据库的用户名和密码,以及端口设置和数据库名称。请记住使用您自己的信息更新此处列出的用户名、密码和数据库名称:

1[label ~/node_project/.env]
2MONGO_USERNAME=sammy
3MONGO_PASSWORD=your_password
4MONGO_PORT=27017
5MONGO_DB=sharkinfo

注意,您已经移除 原来出现在db.js中的host设置。现在,您将在Docker合成文件级别定义您的主机,以及有关您的服务和容器的其他信息。

编辑完成后保存并关闭此文件。

因为您的.env文件包含敏感信息,所以您需要确保它包含在项目的.dockernore.gitignore文件中,这样它就不会复制到版本控制或容器中。

打开.dockerignore文件:

1nano .dockerignore

将以下行添加到文件的底部:

1[label ~/node_project/.dockerignore]
2...
3.gitignore
4.env

编辑完成后,保存并关闭文件。

该存储库中的.gitignore文件已经包含.env,但请检查是否存在:

1nano .gitignore
1[label ~~/node_project/.gitignore]
2...
3.env
4...

至此,您已经成功地从项目代码中提取了敏感信息,并采取措施控制了这些信息的复制方式和位置。现在,您可以添加到数据库连接代码中,以针对容器化工作流对其进行优化。

第三步-修改数据库连接设置

下一步是通过添加代码来处理应用程序无法连接到数据库的情况,从而使数据库连接方法更加健壮。在使用Compose处理容器时,将这种级别的弹性引入应用程序代码是推荐做法

打开db.js进行编辑:

1nano db.js

注意前面添加的代码,以及用于Mongo的连接URI的url常量和Mongooseconnect方法:

 1[label ~/node_project/db.js]
 2...
 3const {
 4  MONGO_USERNAME,
 5  MONGO_PASSWORD,
 6  MONGO_HOSTNAME,
 7  MONGO_PORT,
 8  MONGO_DB
 9} = process.env;
10
11const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;
12
13mongoose.connect(url, {useNewUrlParser: true});

目前,您的Connect方法接受一个选项,该选项告诉Mongoose使用Mongo的新URL parser.您可以向此方法添加选项以定义重新连接尝试的参数。除了新的URL解析器选项外,还可以通过创建包含相关信息的options常量来实现这一点。在您的Mongo常量下面,为options常量添加以下定义:

 1[label ~/node_project/db.js]
 2...
 3const {
 4  MONGO_USERNAME,
 5  MONGO_PASSWORD,
 6  MONGO_HOSTNAME,
 7  MONGO_PORT,
 8  MONGO_DB
 9} = process.env;
10
11const options = {
12  useNewUrlParser: true,
13  reconnectTries: Number.MAX_VALUE,
14  reconnectInterval: 500, 
15  connectTimeoutMS: 10000,
16};
17...

reConnectTries选项告诉Mongoose继续无限期地尝试连接,而reConnectInterval则以毫秒为单位定义连接间隔时间。ConnectTimeoutMS定义Mongo驱动在连接尝试失败之前等待的时间为10秒。

现在您可以在MongooseConnect方法中使用新的options常量来微调您的Mongoose连接设置。您还将添加一个promise来处理潜在的连接错误。

目前,Mongoose的Connect方法如下所示:

1[label ~/node_project/db.js]
2...
3mongoose.connect(url, {useNewUrlParser: true});

删除现有的connect方法,并将其替换为以下代码,其中包括options常量和一个promise:

1[label ~/node_project/db.js]
2...
3mongoose.connect(url, options).then( function() {
4  console.log('MongoDB is connected');
5})
6  .catch( function(err) {
7  console.log(err);
8});

在成功连接的情况下,您的函数会记录相应的消息;否则它会catch并记录错误,以便您进行故障排除。

完成的文件将如下所示:

 1[label ~/node_project/db.js]
 2const mongoose = require('mongoose');
 3
 4const {
 5  MONGO_USERNAME,
 6  MONGO_PASSWORD,
 7  MONGO_HOSTNAME,
 8  MONGO_PORT,
 9  MONGO_DB
10} = process.env;
11
12const options = {
13  useNewUrlParser: true,
14  reconnectTries: Number.MAX_VALUE,
15  reconnectInterval: 500,
16  connectTimeoutMS: 10000,
17};
18
19const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;
20
21mongoose.connect(url, options).then( function() {
22  console.log('MongoDB is connected');
23})
24  .catch( function(err) {
25  console.log(err);
26});

编辑完成后,保存并关闭该文件。

现在,您已经为应用程序代码添加了弹性,以处理应用程序可能无法连接到数据库的情况。准备好这些代码后,您可以继续使用Compose定义您的服务。

第四步-用Docker组合定义服务

重构代码后,您就可以编写带有服务定义的docker-compose.yml文件了。A_SERVICE_IN COMPAGE是一个运行的容器,服务定义--您将包含在您的docker-compose.yml文件中--包含每个容器镜像将如何运行的信息。组合工具允许您定义多个服务来构建多容器应用程序。

在定义服务之前,您将向项目中添加一个名为wait-for的工具,以确保应用程序仅在数据库启动任务完成后尝试连接数据库。此包装器脚本使用netcat轮询特定主机和端口是否接受TCP连接。使用它可以通过测试数据库是否准备好接受连接来控制应用程序连接到数据库的尝试。

尽管Compose允许您使用Dependers_on‘option](https://docs.docker.com/compose/compose-file/#depends_on),指定服务之间的依赖关系,但这个顺序是基于容器是否正在运行而不是它的就绪状态。使用Dependers_on并不适合您的设置,因为您希望您的应用程序仅在数据库启动任务(包括向admin身份验证数据库添加用户和密码)完成后才连接。有关使用Wait-for`等工具控制启动顺序的更多信息,请参考Compose documentation.中的相关[建议

打开名为Wait-for.sh的文件:

1nano wait-for.sh

在文件中输入以下代码以创建轮询函数:

 1[label ~/node_project/app/wait-for.sh]
 2#!/bin/sh
 3
 4# original script: https://github.com/eficode/wait-for/blob/master/wait-for
 5
 6TIMEOUT=15
 7QUIET=0
 8
 9echoerr() {
10  if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
11}
12
13usage() {
14  exitcode="$1"
15  cat << USAGE >&2
16Usage:
17  $cmdname host:port [-t timeout] [-- command args]
18  -q | --quiet Do not output any status messages
19  -t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout
20  -- COMMAND ARGS Execute command with args after the test finishes
21USAGE
22  exit "$exitcode"
23}
24
25wait_for() {
26  for i in `seq $TIMEOUT` ; do
27    nc -z "$HOST" "$PORT" > /dev/null 2>&1
28
29    result=$?
30    if [ $result -eq 0 ] ; then
31      if [ $# -gt 0 ] ; then
32        exec "$@"
33      fi
34      exit 0
35    fi
36    sleep 1
37  done
38  echo "Operation timed out" >&2
39  exit 1
40}
41
42while [ $# -gt 0 ]
43do
44  case "$1" in
45    *:* )
46    HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
47    PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
48    shift 1
49    ;;
50    -q | --quiet)
51    QUIET=1
52    shift 1
53    ;;
54    -t)
55    TIMEOUT="$2"
56    if [ "$TIMEOUT" = "" ]; then break; fi
57    shift 2
58    ;;
59    --timeout=*)
60    TIMEOUT="${1#*=}"
61    shift 1
62    ;;
63    --)
64    shift
65    break
66    ;;
67    --help)
68    usage 0
69    ;;
70    *)
71    echoerr "Unknown argument: $1"
72    usage 1
73    ;;
74  esac
75done
76
77if [ "$HOST" = "" -o "$PORT" = "" ]; then
78  echoerr "Error: you need to provide a host and port to test."
79  usage 2
80fi
81
82wait_for "$@"

添加完代码后,保存并关闭该文件。

使脚本可执行:

1chmod +x wait-for.sh

接下来,打开docker-compose.yml文件:

1nano docker-compose.yml

首先,通过在文件中添加以下代码来定义nodejs应用服务:

 1[label ~/node_project/docker-compose.yml]
 2version: '3'
 3
 4services:
 5  nodejs:
 6    build:
 7      context: .
 8      dockerfile: Dockerfile
 9    image: nodejs
10    container_name: nodejs
11    restart: unless-stopped
12    env_file: .env
13    environment:
14      - MONGO_USERNAME=$MONGO_USERNAME
15      - MONGO_PASSWORD=$MONGO_PASSWORD
16      - MONGO_HOSTNAME=db
17      - MONGO_PORT=$MONGO_PORT
18      - MONGO_DB=$MONGO_DB 
19    ports:
20      - "80:8080"
21    volumes:
22      - .:/home/node/app
23      - node_modules:/home/node/app/node_modules
24    networks:
25      - app-network
26    command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js

nodejs服务定义包括以下选项:

  • build:这定义了配置选项,包括contextdockerfile,当Compose构建应用程序映像时将应用这些选项。如果你想使用像Docker Hub这样的注册表中的现有镜像,你可以使用image指令,其中包含关于你的用户名、存储库和镜像标签的信息。
  • context:这定义了镜像构建的构建上下文-在本例中,是当前项目目录。
  • dockerfile:指定当前项目目录中的Dockerfile,因为Compose将使用该文件构建应用程序映像。有关此文件的详细信息,请参阅如何使用Docker构建Node.js应用程序
  • imagecontainer_name:这些将名称应用于图像和容器。
  • restart:定义重启策略。默认值为no,但您已将容器设置为除非停止否则将重新启动。
  • env_file:这告诉Compose你想从一个名为.env的文件中添加环境变量,该文件位于你的构建上下文中。
  • environment:使用此选项可以添加您在.env文件中定义的Mongo连接设置。请注意,您没有将NODE_ENV设置为development,因为如果没有设置NODE_ENV,这是Express的[默认](https://github.com/expressjs/express/blob/dc 538 f6 e810 bd 462 c98 ee 7 e6 ae 24 c64 d4 b1 da 93/lib/application.js# L71)行为。迁移到生产环境时,您可以将其设置为production以[启用视图缓存和更少的详细错误消息](https://expressjs.com/en/advanced/best-practice-performance.html set-node_env-to-production)。

还要注意,您已经指定了db数据库容器作为主机,如步骤2.]中所讨论的

  • ports:将主机上的80端口映射到容器上的8080端口。
  • volumes:这里包含两种挂载类型: -第一个是绑定mount,将您在宿主机上的应用代码挂载到容器上的/home/node/app目录中。这将有助于快速开发,因为您对主机代码所做的任何更改都将立即填充到容器中。 -第二个是命名volumenode_modes。当Docker运行应用程序Dockerfile中列出的npm install指令时,npm会在容器上创建一个新的node_modules目录,其中包含运行应用程序所需的包。但是,您刚刚创建的绑定挂载将隐藏这个新创建的node_modes目录。由于主机上的node_modes为空,绑定会将一个空目录映射到容器,覆盖新的node_modes目录,并阻止您的应用程序启动。命名为node_modes的卷通过持久化/home/node/app/node_modes目录的内容并将其挂载到容器中,隐藏绑定来解决此问题。

<$>[注] 使用此方法时请记住以下几点

  • 您的绑定将把容器上的node_modules目录的内容挂载到主机上,这个目录将由root拥有,因为命名卷是由Docker创建的。
  • 如果主机上已有node_modules目录,它将覆盖容器上创建的node_modules目录。在本教程中构建的设置假定您 ** 没有 预先存在的node_modules目录,并且您不会在主机上使用npm。这与应用程序开发的十二因素方法保持一致,该方法最大限度地减少了执行环境之间的依赖性。

<$>

  • networks:指定您的应用程序服务将加入app-network网络,您将在文件底部定义该网络。
  • command:设置Compose运行镜像时应该执行的命令。请注意,这将覆盖您在我们的应用程序Dockerfile中设置的CMD指令。在这里,您正在使用wait-for脚本运行应用程序,该脚本将轮询端口27017上的db服务,以测试数据库服务是否就绪。一旦就绪测试成功,脚本将执行您设置的命令/home/node/app/node_modules/.bin/nodemon app.js,以nodemon启动应用程序。这将确保您将来对代码所做的任何更改都可以重新加载,而无需重新启动应用程序。

接下来,通过在应用服务定义下面添加以下代码来创建db服务:

 1[label ~/node_project/docker-compose.yml]
 2...
 3  db:
 4    image: mongo:4.1.8-xenial
 5    container_name: db
 6    restart: unless-stopped
 7    env_file: .env
 8    environment:
 9      - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
10      - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
11    volumes:  
12      - dbdata:/data/db   
13    networks:
14      - app-network

nodejs服务定义的一些设置保持不变,但您还对ImageEnvironmentvolumes定义进行了以下更改:

  • Image:为了创建该服务,Compose会拉取4.1.8-xiial[Mongo镜像](来自Docker Hub的https://hub.docker.com/_/mongo))。您正在固定一个特定的版本,以避免将来在Mongo映像更改时可能发生的冲突。有关版本钉住的更多信息,请参阅DockerFILE BEST practices.]上的Docker文档
  • MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORDmongo镜像使这些环境variables]可用,以便您可以修改数据库实例的初始化。MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORD共同在admin鉴权数据库中创建一个root用户,并确保容器启动时开启鉴权。您已经使用.env文件中的值设置了MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORD,您可以使用env_file选项将该文件传递给db服务。这样做意味着您的sammy应用程序用户将是数据库实例上的[rootuser](https://docs.mongodb.com/manual/reference/built-in-roles/ root)],可以访问该角色的所有管理和操作权限。在生产环境中工作时,您需要创建具有适当作用域权限的专用应用程序用户。

<$>[备注] 注意: 请记住,如果您在已有数据目录的情况下启动容器,这些变量将不会生效。 <$>

  • dbdata:/data/db:命名卷dbdata会持久化Mongo的[默认数据数据/directory](https://docs.mongodb.com/manual/reference/configuration-options/#storage.dbPath),/db中的数据。这将确保您在停止或删除容器时不会丢失数据。

db服务也通过networks选项添加到了app-network网络中。

最后一步,将卷和网络定义添加到文件底部:

1[label ~/node_project/docker-compose.yml]
2...
3networks:
4  app-network:
5    driver: bridge
6
7volumes:
8  dbdata:
9  node_modules:

用户自定义网桥网络app-network支持您的容器之间的通信,因为它们位于同一个Docker守护程序主机上。这简化了应用程序内的通信和通信,因为它打开了同一网桥网络上的容器之间的所有端口,而不向外部世界公开任何端口。这样,您的dbnodejs容器就可以相互通信了,您只需要公开80端口就可以前端访问应用程序。

您的顶级volumes密钥定义了卷dbdatanode_modes。当Docker创建卷时,卷的内容存储在由Docker管理的主机文件系统/var/lib/docker/volures/的一部分中。每个卷的内容都存储在/var/lib/docker/volvures/下的一个目录中,并挂载到使用该卷的任何容器中。如此一来,即使您移除并重新创建了db容器,您的用户将创建的Shark信息数据也会保留在dbdata卷中。

完成的docker-compose.yml文件如下所示:

 1[label ~/node_project/docker-compose.yml]
 2version: '3'
 3
 4services:
 5  nodejs:
 6    build:
 7      context: .
 8      dockerfile: Dockerfile
 9    image: nodejs
10    container_name: nodejs
11    restart: unless-stopped
12    env_file: .env
13    environment:
14      - MONGO_USERNAME=$MONGO_USERNAME
15      - MONGO_PASSWORD=$MONGO_PASSWORD
16      - MONGO_HOSTNAME=db
17      - MONGO_PORT=$MONGO_PORT
18      - MONGO_DB=$MONGO_DB
19    ports:
20      - "80:8080"
21    volumes:
22      - .:/home/node/app
23      - node_modules:/home/node/app/node_modules
24    networks:
25      - app-network
26    command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js 
27
28  db:
29    image: mongo:4.1.8-xenial
30    container_name: db
31    restart: unless-stopped
32    env_file: .env
33    environment:
34      - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
35      - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
36    volumes:     
37      - dbdata:/data/db
38    networks:
39      - app-network  
40
41networks:
42  app-network:
43    driver: bridge
44
45volumes:
46  dbdata:
47  node_modules:

完成编辑后保存并关闭文件。

服务定义就绪后,您就可以启动应用程序了。

第五步-测试应用程序

准备好docker-compose.yml文件后,您可以使用docker-compose up命令创建您的服务。您还可以通过使用docker-compose down.]停止和移除容器来测试您的数据是否会持久存在

首先构建容器镜像并创建服务,运行带有-d标志的docker-compose up,然后在后台运行nodejsdb容器:

1docker-compose up -d

输出确认您的服务已创建:

1[secondary_label Output]
2...
3Creating db ... done
4Creating nodejs ... done

您还可以通过显示服务的日志输出来获取有关启动进程的更详细信息:

1docker-compose logs

如果一切正常启动,则输出如下:

1[secondary_label Output]
2...
3nodejs    | [nodemon] starting `node app.js`
4nodejs    | Example app listening on 8080!
5nodejs    | MongoDB is connected
6...
7db        | 2019-02-22T17:26:27.329+0000 I ACCESS   [conn2] Successfully authenticated as principal sammy on admin

您还可以使用docker-Compose ps:]检查容器的状态

1docker-compose ps

输出表明您的容器正在运行:

1[secondary_label Output]
2 Name Command State Ports        
3----------------------------------------------------------------------
4db docker-entrypoint.sh mongod Up 27017/tcp           
5nodejs   ./wait-for.sh db:27017 --  ... Up 0.0.0.0:80->8080/tcp

当您的服务正在运行时,您可以在浏览器中访问http://your_server_ip

Everything Sharks应用程序登陆Page

点击获取鲨鱼信息 按钮,进入一个带有条目表格的页面,您可以在其中提交鲨鱼名称和该鲨鱼的一般特征的描述:

鲨鱼信息表单,您可以在其中输入鲨鱼名称和该shark的特征

在表格中,添加您选择的鲨鱼。出于演示的目的,在鲨鱼名称 字段中添加Megalodon Shark,在** 鲨鱼字符** 字段中添加Ancient

Fill Shark Form

点击提交 按钮,您将看到一个包含该鲨鱼信息的页面:

Form You submitted的Shark输出

作为最后一步,测试如果删除数据库容器,您刚才输入的数据是否会持续存在。

回到您的终端,键入以下命令以停止并删除您的容器和网络:

1docker-compose down

请注意,您没有包含--volumes选项;因此,您的dbdata卷不会被删除。

以下输出确认您的容器和网络已被删除:

1[secondary_label Output]
2Stopping nodejs ... done
3Stopping db     ... done
4Removing nodejs ... done
5Removing db     ... done
6Removing network node_project_app-network

重新创建容器:

1docker-compose up -d

现在回到鲨鱼信息表:

鲨鱼信息表

进入你选择的一只新鲨鱼。本例将使用鲸鲨大鲨鱼

输入新Shark

单击提交 后,您会注意到,新的Shark已添加到数据库的Shark集合中,并且不会丢失您已经输入的数据:

完整的鲨鱼Collection

您的应用程序现在运行在已启用数据持久化和代码同步的Docker容器上。

结论

通过学习本教程,您已经使用Docker Containers为您的Node应用程序创建了开发设置。通过提取敏感信息并将应用程序的状态与应用程序代码分离,您的项目变得更加模块化和可移植。您还配置了一个样板docker-compose.yml文件,您可以根据开发需求和要求的变化进行修改。

在开发过程中,您可能会有兴趣了解更多有关为容器化和云Native工作流]设计应用程序的信息。有关这些主题的更多信息,请参阅构建Kubernetes应用程序和现代化Kubernetes应用程序]。

要了解本教程中使用的代码的更多信息,请参阅如何使用Docker构建Node.js应用程序》和如何将MongoDB与您的节点Application.集成使用容器部署Node应用的相关信息,请参阅如何使用NGINX保护容器化的Node.js应用》、《让我们加密吧》和Docker Compose.

Published At
Categories with 技术
comments powered by Disqus