docker - 如何链接多个Docker容器并封装结果?

标签 docker encapsulation docker-networking

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

我的直觉是运行嵌套在应用程序容器内的Neo4j容器。但是从我阅读的内容来看,我认为支持/推荐的方法是将容器链接在一起。我需要的东西在this image中已经很好地说明了。但是图像来源的the article对我来说还不清楚。无论如何,它正在使用即将弃用的legacy container linking,而最近推荐使用networking。教程或解释将不胜感激。

另外,docker-compose如何适合所有这些?

最佳答案

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

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

虽然大多数人会告诉您不要在Docker容器中运行多个进程,但没有什么可以阻止您这样做。如果要遵循此路径,请查看Docker文档网站上的Using Supervisor with DockerPhusion 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容器进行通信的新方法是创建一个虚拟网络并将这两个容器连接到该网络。

    操作方法如下:
    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应用程序的示例

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

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

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

    Docker化Web应用

    我们需要构建一个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镜像所必须遵循的步骤。该 docker 镜像将:
  • 基于official node docker image
  • Github克隆nodeJS示例项目
  • 将工作目录更改为包含git clone
  • 的目录
  • 运行npm install命令以下载并安装nodeJS应用程序依赖项
  • 指示docker在运行该图像的容器时使用哪个命令

  • 快速查看一下nodeJS代码,发现作者允许我们使用NEO4J_URL环境变量来配置要用于connect to the neo4j database的URL。

    Docker化neo4j数据库

    好吧,人们已经为我们照顾好了。我们将使用Docker Hub上的official Docker image for neo4j

    快速阅读自述文件,告诉我们使用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服务将从官方neo4j docker镜像生成一个名为my-neo4j-db的容器,并将启动该容器,将NEO4J_AUTH环境变量设置为none
    web服务将使用从当前目录(build: .)中找到的Dockerfile构建的docker镜像生成一个以docker compose斟酌命名的容器。它将启动该容器,将环境变量NEO4J_URL设置为http://my-neo4j-db:7474(请注意,我们在此处使用neo4j容器my-neo4j-db的名称)。此外,docker compose将指示Docker引擎在docker主机端口web上公开3000容器的端口80

    开火

    确保您位于包含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目录,并将其安装在位置/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文件的目录中,才能启动第二个实例。

    关于docker - 如何链接多个Docker容器并封装结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34694933/

    相关文章:

    api - API 中要公开多少低级内容?

    docker - docker的RabbitMQ集群-在不同的主机和不同的项目上组成

    docker - Docker每个网络端口映射

    docker - 如何使用Docker远程API使用另一个容器的网络 namespace 创建容器

    docker - 获取用于启动 Docker 容器的命令

    docker - 在 Windows 主机上的 docker 容器内更改挂载文件夹中的文件权限

    java - Clojure 和 Java 之间的界限在哪里?

    json - 错误发生为:w0无法读取json文件,并显示以下错误:使用docker-compose启动沙发基础图像时,无法解码JSON对象

    django - 通过 shell 记录时未设置 Docker 环境变量

    javascript - Javascript中的封装与继承