使用基于库的网络应用程序作为容器部署节点


码头工人越来越受欢迎,我一直在慢慢地把它引入我的项目。它使得分发您的应用程序变得容易,因为无论您在哪里部署您的容器,体验都是一样的。以节点为例。Node.js有许多版本,尽管它们通常不管网络应用场景如何都可以工作,但你不能真正确定。

我们将看到如何建立一个自定义CouchbaseNoSQL容器,并将其部署在使用Couchbase容器的自定义Node.js网络应用程序容器旁边。

如果这是你第一次接触Docker让我们分解我们希望实现的目标。Couchbase发布了一个正式的Docker图像Docker Hub,但该映像未预配。这并不是一件坏事,它绝对是我们在数据库容器中所期望的。这意味着我们需要在官方图像的基础上创建一个自定义图像,否则当我们部署Couchbase时,它将不会被设置。当涉及到Node.js时,我们将创建一个应用程序并将它打包到一个Docker容器中。这两个Couchbase和Node.js Docker容器将能够相互通信。

创建自定义Couchbase服务器Docker映像和容器

在您的计算机上创建一个目录,并包含以下两个文件:

Dockerfile
configure.sh

Dockerfile文件将代表我们的自定义映像,而configure.sh文件将是我们部署容器时的运行时脚本。

打开Dockerfile文件,包括以下内容:

FROM couchbase

COPY configure.sh /opt/couchbase

CMD ["/opt/couchbase/configure.sh"]

我们的自定义图像将使用官方的Couchbase图像作为基础。在构建时,配置脚本将被复制到映像中。运行时,脚本将被执行。让我们看看那个脚本。

打开configure.sh文件,包括以下内容:

set -m

/entrypoint.sh couchbase-server &

sleep 15

curl -v -X POST http://127.0.0.1:8091/pools/default -d memoryQuota=512 -d indexMemoryQuota=512

curl -v http://127.0.0.1:8091/node/controller/setupServices -d services=kv%2cn1ql%2Cindex

curl -v http://127.0.0.1:8091/settings/web -d port=8091 -d username=$COUCHBASE_ADMINISTRATOR_USERNAME -d password=$COUCHBASE_ADMINISTRATOR_PASSWORD

curl -i -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD -X POST http://127.0.0.1:8091/settings/indexes -d 'storageMode=memory_optimized'

curl -v -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD -X POST http://127.0.0.1:8091/pools/default/buckets -d name=$COUCHBASE_BUCKET -d bucketType=couchbase -d ramQuotaMB=128 -d authType=sasl -d saslPassword=$COUCHBASE_BUCKET_PASSWORD

sleep 15

curl -v http://127.0.0.1:8093/query/service -d "statement=CREATE PRIMARY INDEX ON `$COUCHBASE_BUCKET`"

fg 1

同样,configure.sh脚本的目的是在服务器启动后对其进行资源调配。要做到这一点,我们可以利用库基RESTful应用编程接口。该配置包括创建集群、启用Couchbase服务、定义管理凭据、创建存储桶以及在存储桶上创建N1QL索引。

在配置脚本中,您会注意到使用了几个环境变量,例如$COUCHBASE_ADMINISTRATOR_USERNAME变量。这将避免我们将潜在的敏感信息硬编码到图像中。相反,我们可以在部署时定义这些变量。

现在,让我们为我们的项目构建定制的Couchbase图像。在码头工人外壳中,执行以下操作:

docker build -t couchbase-custom /path/to/directory/with/dockerfile

在上面的命令中couchbase-custom文本是我们图像的名称,而路径是我们Dockerfile和configure.sh文件的路径。

为Couchbase创建自定义映像后,执行以下命令来运行它:

docker run -d \
-p 8091-8093:8091-8093 \
-e COUCHBASE_ADMINISTRATOR_USERNAME=Administrator \
-e COUCHBASE_ADMINISTRATOR_PASSWORD=password \
-e COUCHBASE_BUCKET=default \
-e COUCHBASE_BUCKET_PASSWORD= \
--network="docker_default" \
--name couchbase \
couchbase-custom

上面的命令说我们想要部署一个容器,映射每个必需的Couchbase端口。我们传入在configure.sh脚本中找到的环境变量,并定义希望容器在哪个网络上运行。容器将被命名couchbase,它也将是容器的主机名。

创建一个网络应用程序

随着Couchbase的启动和运行,我们可以开发一个简单的Node.js应用程序。首先,在你的电脑上创建一个目录来代表我们的项目。在该项目中,创建一个app.js文件。从命令提示符或终端,执行以下操作:

npm init --y

上面的命令将创建一个非常基本的包. json文件,这将是我们的Node.js应用程序的基础。有一些必须安装的依赖项,所以让我们执行以下步骤来获取它们:

npm install express couchbase body-parser uuid --save

我们将使用express为了建立我们的应用编程接口,couchbase作为我们的软件开发工具包,body-parser用于处理开机自检正文,以及uuid用于生成代表文档键的唯一id值。

有了应用程序基础,我们就可以开始开发应用程序了。打开项目的app.js文件,并包含以下代码:

var Couchbase = require("couchbase");
var Express = require("express");
var BodyParser = require("body-parser");
var UUID = require("uuid");

var app = Express();
var N1qlQuery = Couchbase.N1qlQuery;
var bucket = (new Couchbase.Cluster("couchbase://" + process.env.COUCHBASE_HOST)).openBucket(process.env.COUCHBASE_BUCKET, process.env.COUCHBASE_BUCKET_PASSWORD);

app.use(BodyParser.json());

app.get("/", function(request, response) {
    response.send("Try using the `/get` or `/save` endpoints!");
});

app.get("/get", function(request, response) {
    var query = N1qlQuery.fromString("SELECT `" + bucket._name + "`.* FROM `" + bucket._name + "`");
    bucket.query(query, function(error, result) {
        if(error) {
            return response.status(500).send(error);
        }
        response.send(result);
    });
});

app.post("/save", function(request, response) {
    bucket.insert(UUID.v4(), request.body, function(error, result) {
        if(error) {
            return response.status(500).send(error);
        }
        response.send(result);
    });
});

var server = app.listen(process.env.APPLICATION_PORT || 3000, function() {
    console.log("Listening on port " + server.address().port + "...");
});

那么在上面的代码中发生了什么?

首先,我们导入所有下载的依赖项,然后建立到Couchbase的连接。你会注意到我们正在使用process.env贯穿整个代码。这允许我们读取环境变量。我们将使用与我们在Couchbase图片中看到的类似的方法。

该应用编程接口有两个端点,实际上可以做任何事情。这/save端点将插入请求正文中的任何内容/get端点将查询Couchbase中保存的任何内容。

网络应用的容器化

随着应用程序的构建,我们需要将它包装起来,这样就可以很容易地用Docker进行部署。在与package.json文件相同的目录中,添加以下两个文件:

Dockerfile
.dockerignore

该计划是基于官方的Node.js Docker图像创建一个自定义图像。在Dockerfile文件中,包括以下内容:

FROM node:6-alpine

COPY . /srv/
WORKDIR /srv

RUN /usr/local/bin/npm install

CMD /usr/local/bin/node app.js

在映像构建期间,我们将把项目复制到映像文件系统中,并更改工作目录。然后我们将安装在package.json文件中找到的所有依赖项。部署容器后,将运行app.js文件。

您可能想知道为什么我们在构建映像时要进行安装。我们这样做是因为我们不想将依赖关系复制到映像中,因为可能存在操作系统和架构不兼容的情况。排除node_modules目录,包括以下内容.dockerignore文件:

node_modules

您想要从图像中排除的任何内容都可以进入该文件。

要构建此映像,请在Docker Shell中执行以下操作:

docker build -t nodejs-custom /path/to/directory/with/dockerfile

我们的节点应用程序的图像名将被调用nodejs-custom它将基于包含Dockerfile文件的目录。有关构建自定义Docker映像的更多信息,请参见previous article我写的。

有了图像,我们需要运行它。在码头工人外壳中,执行以下操作:

docker run -d \
-p 3000:3000 \
-e COUCHBASE_HOST=couchbase \
-e COUCHBASE_BUCKET=default \
-e COUCHBASE_BUCKET_PASSWORD= \
-e APPLICATION_PORT=3000 \
--network="docker_default" \
--name nodejs \
nodejs-custom

上面的命令应该与我们在Couchbase部署中看到的内容相似。我们正在定义应用程序的端口映射,传递app.js文件中使用的环境变量,并定义容器网络和映像名称。

如果你去你的网络浏览器并导航到网络应用的任何一个端点,它应该可以正常工作。

使用编写文件部署码头集装箱

为了部署容器,必须记住所有的环境变量和命令中的所有内容,这是很痛苦的。创建一个合成文件可以让事情简单得多。

创建了两个自定义图像后,在计算机上的某个位置创建一个docker-composite . yml文件。该文件应包含以下内容:

version: '2'

services:
    couchbase:
        image: couchbase-custom
        ports:
            - 8091:8091
            - 8092:8092
            - 8093:8093
        environment:
            - COUCHBASE_ADMINISTRATOR_USERNAME=Administrator
            - COUCHBASE_ADMINISTRATOR_PASSWORD=password
            - COUCHBASE_BUCKET=default
            - COUCHBASE_BUCKET_PASSWORD=

    nodejs:
        image: nodejs-custom
        ports:
            - 3000:3000
        environment:
            - COUCHBASE_HOST=couchbase
            - COUCHBASE_BUCKET=default
            - COUCHBASE_BUCKET_PASSWORD=
            - APPLICATION_PORT=3000
        restart: always

使用撰写时,您不必担心定义网络,因为文件中的所有内容都在同一个网络上。要启动其中一个容器,您可以执行以下操作:

docker-compose run -d --service-ports --name couchbase couchbase

有了Couchbase,你不能把所有的事情都拼凑起来,因为Couchbase没有办法告诉你什么时候准备好了。因此,Node.js应用程序可能会在Couchbase准备好接受连接之前尝试连接。

docker-compose up -d

上面的命令通常会旋转合成文件中的所有容器,但是我们不能在这个场景中使用它。

结论

如果您想知道如何使用Couchbase网络应用程序部署您的Node.js,Docker是一个简单的解决方案。在构建了Couchbase或Node.js的映像后,您可以相信它将在运行Docker引擎的任何服务器或计算机上运行。