3

我有一个连接到 Neo4j 数据库的 Node.js Web 应用程序。我想将这些封装在单个 Docker 映像中(也使用Neo4j Docker 容器),但我是 docker 新手,似乎无法弄清楚这一点。在最新的 Docker 版本中推荐的方法是什么?

我的直觉是运行嵌套在应用容器内的 Neo4j 容器。但从我读过的内容来看,我认为支持/推荐的方法是将容器链接在一起。这张图片很好地说明了我需要的东西。但是我不清楚图像来自哪里的文章。无论如何,它正在使用即将被弃用的遗留容器链接,而这些天推荐使用网络。教程或解释将不胜感激。

另外,docker-compose如何适应这一切?

4

1 回答 1

13

在另一个容器中运行一个容器意味着在一个 Docker 容器中运行一个Docker 引擎。这被称为Docker-in-Docker 的dind,我强烈建议不要这样做。您可以在线搜索“dind”并发现为什么在大多数情况下这是一个坏主意,但由于它不是您问题的主要对象,我不会进一步扩展这个主题。

在同一个容器中同时运行 node.js 进程和 neo4j 进程

虽然大多数人会告诉你不要在 Docker 容器中运行多个进程,但没有什么能阻止你这样做。如果您想遵循此路径,请查看Docker 文档网站中的Using Supervisor with Docker ,或Phusion baseimage Docker 映像。

请注意,这种做事方式会使您的 Docker 映像随着时间的推移越来越难以维护。

链接容器

正如您所发现的,从长远来看,保持 Docker 映像尽可能简单(即:在 Docker 容器中运行一个且仅一个应用程序)将使您的生活更轻松。

当两个容器在同一个 Docker 引擎上运行时,将容器链接在一起是微不足道的。这只是一个问题:

  • 让您的 neo4j 容器公开其服务侦听的端口
  • --link <neo4j container name>:<alias>使用选项运行 node.js 容器
  • 在 node.js 应用程序配置中,将 neo4j 主机设置为<alias>主机名,docker 将负责将该连接转发到它分配给 neo4j 容器的 IP

当你想在不同的主机上运行这两个容器时,事情变得更加困难。

使用 Docker Compose,您必须使用link:密钥来定义链接

新的 Docker 网络功能

您还发现,未来将不支持链接容器,并且使多个 Docker 容器通信的新方法是创建一个虚拟网络并将这两个容器附加到该网络。

以下是如何进行:

docker network create mynet
docker run --detach --name myneo4j --net mynet neo4j
docker run --detach --name mynodejs --net mynet <your nodejs image>

然后,您的节点应用程序配置应用myneo4j作要连接的主机。

要告诉 Docker Compose 使用新的网络功能,您必须使用该--x-networking选项。你也不会使用links:密钥。

使用新的网络功能还意味着您将无法为 db 定义任何别名。因此,您必须使用容器名称。请注意,除非您在docker-compose.ymlcontainer_name:文件中使用密钥,否则Compose 将根据包含docker-compose.yml文件的目录、在 yml 文件中找到的服务名称和一个数字来创建容器名称。

例如,以下docker-compose.yml文件,如果在名为“foo”的目录中,将创建两个名为foo_web_1and的容器foo_db_1

web:
  build: .
  ports:
    - "8000:8000"
db:
  image: postgres

以 开头时docker-compose --x-networking up,Web 应用程序配置应用foo_db_1作 db 主机名。

而如果你使用container_name

web:
  build: .
  ports:
    - "8000:8000"
db:
  image: postgres
  container_name: mydb

以 开头时docker-compose --x-networking up,Web 应用程序配置应用mydb作 db 主机名。


使用 Docker Compose 运行使用 nodeJS 和 neo4j 的 Web 应用程序的示例

在此示例中,我将展示如何将使用 nodejs 和 neo4j的 github 项目 aseemk/node-neo4j-template中的示例应用程序 dockerize。

我假设您已经安装了Docker 1.9.0+ 和Docker Compose 1.5+。

该项目将使用 2 个 docker 容器,一个用于运行 neo4j 数据库,一个用于运行 nodeJS Web 应用程序。

将 Web 应用程序 Docker 化

我们需要构建一个Docker 镜像,Docker compose 将从该镜像运行一个容器。为此,我们将编写一个Dockerfile

创建一个名为Dockerfile(注意大写D)的文件,其内容如下:

FROM node
RUN git clone https://github.com/aseemk/node-neo4j-template.git
WORKDIR /node-neo4j-template
RUN npm install
# ugly 20s sleep to wait for neo4j to initialize
CMD sleep 20s && node app.js

Dockerfile描述了Docker 引擎为我们的 Web 应用程序构建Docker映像必须遵循的步骤。此泊坞窗图像将:

  • 基于官方node docker镜像
  • 从Github克隆 nodeJS 示例项目
  • 将工作目录更改为包含 git clone 的目录
  • 运行npm install命令以下载并安装 nodeJS 应用程序依赖项
  • 指示 docker 在运行该映像的容器时使用哪个命令

对 nodeJS 代码的快速回顾表明,作者允许我们使用环境变量配置用于连接 neo4j 数据库的 URL。NEO4J_URL

对 neo4j 数据库进行 Docker 化

好吧,人们已经为我们解决了这个问题。我们将使用可在 Docker Hub 上找到的 neo4j 的官方 Docker 镜像。

快速查看自述文件告诉我们使用NEO4J_AUTH环境变量来更改 neo4j 密码。并将此变量设置为none将一起禁用身份验证。

设置 Docker Compose

在与包含我们的Dockerfile的目录相同的目录中,创建一个docker-compose.yml文件,其内容如下:

db:
  container_name: my-neo4j-db
  image: neo4j
  environment:
    NEO4J_AUTH: none

web:
  build: .
  environment:
    NEO4J_URL: http://my-neo4j-db:7474
  ports:
    - 80:3000

此 Compose 配置文件描述了 2 个服务:dbweb.

db服务将生成一个以my-neo4j-db官方neo4j docker映像命名的容器,并将启动该容器,并将NEO4J_AUTH环境变量设置为none.

web服务将使用从当前目录( build: .) 中找到的 Dockerfile 构建的 docker 映像生成一个名为 docker compose 的容器。它将启动该容器,将环境变量设置NEO4J_URLhttp://my-neo4j-db:7474(注意我们在这里如何使用 neo4j 容器的名称my-neo4j-db)。此外,docker compose 将指示 Docker 引擎在 docker 主机端口上公开web容器的端口。300080

开火

确保您位于包含docker-compose.yml文件的目录中并输入:docker-compose --x-networking up

Docker compose 将读取docker-compose.yml文件,确定它必须首先为web服务构建一个 docker 映像,然后创建并启动两个容器,最后将为您提供来自两个容器的日志。

一旦日志显示web_1 | Express server listening at: http://localhost:3000/,一切都已准备好,您可以将您的 Internet 导航器指向http://<ip of the docker host>/

要停止应用程序,请点击Ctrl+ C

如果您想在后台启动应用程序,请docker-compose --x-networking up -d改用。然后为了显示日志,运行docker-compose logs.

要停止服务:docker-compose stop

要删除容器:docker-compose rm

使 neo4j 存储持久化

官方的 neo4j docker 镜像自述文件说容器将其数据保存在/data. 然后我们需要指示 Docker Compose 将该卷挂载到 docker 主机上的目录中。

使用以下内容更改docker-compose.yml文件:

db:
  container_name: my-neo4j-db
  image: neo4j
  environment:
    NEO4J_AUTH: none
  volumes:
    - ./neo4j-data:/data

web:
  build: .
  environment:
    NEO4J_URL: http://my-neo4j-db:7474
  ports:
    - 80:3000

使用该配置文件,当您运行时docker-compose --x-networking up,docker compose 将创建一个neo4j-data目录并将其挂载到容器的 location/data中。

启动应用程序的第二个实例

创建一个新目录并复制Dockerfiledocker-compose.yml文件。

然后我们需要编辑docker-compose.yml文件以避免 neo4j 容器的名称冲突和 docker 主机上的端口冲突。

将其内容更改为:

db:
  container_name: my-neo4j-db2
  image: neo4j
  environment:
    NEO4J_AUTH: none
  volumes:
    - ./neo4j-data:/data

web:
  build: .
  environment:
    NEO4J_URL: http://my-neo4j-db2:7474
  ports:
    - 81:3000

现在它已准备好执行docker-compose --x-networking up命令。请注意,您必须在包含新docker-compose.yml文件的目录中才能启动第二个实例。

于 2016-01-09T17:46:47.623 回答