如何link多个Docker容器并封装结果?

How to link multiple Docker containers and encapsulate the result?

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

我的直觉是 运行 Neo4j 容器 嵌套在 应用程序容器中。但是从我读过的内容来看,我认为支持/推荐的方法是 link 将容器放在一起。这些天推荐的 this image. But the article where the image comes from isn't clear to me. Anyway, it's using the soon-to-be-deprecated legacy container linking, while networking 中很好地说明了我需要的东西。教程或解释将不胜感激。

此外,docker-compose 如何适应所有这些?

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

运行 node.js 进程和同一容器中的 neo4j 进程

虽然大多数人会告诉您不要 运行 在一个 Docker 容器中安装多个进程,但没有什么能阻止您这样做。如果您想遵循此路径,请查看 Using Supervisor with Docker from the Docker documentation website, or at the Phusion baseimage Docker 图片。

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

链接容器

如您所见,尽可能简单地保留 Docker 图像(即:运行在 Docker 容器中安装一个应用程序)将使您的生活更轻松从长远来看。

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

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

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

使用 Docker Compose,您必须使用 link: 键来定义您的链接

新的 Docker 网络功能

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

以下是如何进行:

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: 键。

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

例如,下面的 docker-compose.yml 文件,如果在名为 "foo" 的目录中,将创建两个名为 foo_web_1foo_db_1:

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

当以 docker-compose --x-networking up 启动时,Web 应用程序配置应使用 foo_db_1 作为数据库主机名。

而如果您使用 container_name:

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

当使用 docker-compose --x-networking up 启动时,Web 应用程序配置应使用 mydb 作为数据库主机名。


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

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

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

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

Docker正在处理 Web 应用程序

我们需要构建一个 Docker 图像,Docker 将运行 从中构建一个容器。为此,我们将编写一个Docker文件.

创建一个名为 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

这个Docker文件描述了Docker引擎必须遵循的步骤构建一个docker image 用于我们的网络应用程序。此 docker 图片将:

  • 基于official node docker image
  • Github
  • 克隆 nodeJS 示例项目
  • 将工作目录更改为包含 git 克隆的目录
  • 运行 npm install 命令下载并安装 nodeJS 应用依赖项
  • 指示 docker 当 运行 连接该图像的容器时使用哪个命令

快速查看 nodeJS 代码后发现,作者允许我们使用 NEO4J_URL 环境变量配置 URL 以用于 connect to the neo4j database

Docker正在处理 neo4j 数据库

好吧,人们已经为我们解决了这个问题。我们将使用 official Docker image for neo4j,可以在 Docker 集线器上找到。

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

设置Docker撰写

在包含我们的Docker文件的同一目录中,创建一个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 服务将从官方 neo4j docker 镜像生成一个名为 my-neo4j-db 的容器,并将启动该容器设置NEO4J_AUTH 环境变量到 none.

web 服务将生成一个名为 docker 的容器,使用 docker 映像 根据 Docker 中找到的文件构建自由裁量权当前目录 (build: .)。它将启动该容器,将环境变量 NEO4J_URL 设置为 http://my-neo4j-db:7474(注意我们在这里如何使用 neo4j 容器的名称 my-neo4j-db)。此外,docker compose 将指示 Docker 引擎在 docker 主机端口 80.[=77 上公开 web 容器的端口 3000 =]

启动它

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

Docker compose 将读取 docker-compose.yml 文件,弄清楚它必须首先为 web 服务,然后创建并启动两个容器,最后将为您提供两个容器的日志。

一旦日志显示 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 目录并将其安装到位于 [=59 的容器中=].

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

创建一个新目录并复制 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 文件的目录中才能启动第二个实例。