docker 在不同的端口上运行 mongo 映像

Posted

技术标签:

【中文标题】docker 在不同的端口上运行 mongo 映像【英文标题】:docker run mongo image on a different port 【发布时间】:2017-07-30 23:58:32 【问题描述】:

简短的问题是我可以从 mongo 运行 mongo:latest image 在与 27017 不同的端口上(例如在 27018 上吗?)

如果是,我如何在 docker-compose.yml 文件中执行此操作,以便能够键入以下命令:

docker-compose run

更长的故事:

我有一个在 AWS EC2 实例中运行的应用程序。该应用程序由一个 mongodb 和一个 Web 应用程序组成。现在我决定将这个应用程序的一部分分离到它自己的微服务中,在 docker 容器内的同一个 AWS 中运行(两个容器一个用于另一个 mongo,一个用于 Web 应用程序)。我认为问题是我不能让 mongodb 在端口 27017 上运行,同时另一个 mongodb 在端口 27017 上的 docker 容器内运行。对吗?我有这个假设是因为当我停止第一个 mongo(我的应用程序 mongo)时,我的 docker mongo 工作。

所以我正在尝试制作第二个 mongo(位于 docker 容器中的那个),在不同的端口和我的第二个 Web 应用程序(另一个 docker conianter 中的那个)中运行,在不同的端口上收听 mongo港口。这是我更改 docker-compose 文件的尝试:

version: '2'
services:
    webapp:
        image: myimage
        ports:
            - 3000:3000

    mongo:
        image: mongo:latest
        ports:
            - 27018:27018

在我的新应用程序中,我将 mongo url 更改为:

monog_url = 'mongodb://mongo:27018'
client = MongoClient(monog_url, 27018)

好吧,如果我说:

monog_url = 'mongodb://mongo:27018'
client = MongoClient(monog_url)

但是当我运行 docker-compose run 时,它仍然不起作用,并且出现以下错误:

ERROR: for mongo  driver failed programming external
connectivity on endpoint: Error starting userland proxy:
listen tcp 0.0.0.0:27017: bind: address already in use

或者

pymongo.errors.ServerSelectionTimeoutError:
mongo:27018: [Errno -2] Name or service not known

【问题讨论】:

【参考方案1】:

您可以在容器内部和外部在同一端口上运行进程。您甚至可以在内部使用同一个端口运行多个容器。你不能做的是将一个端口从主机映射到一个容器。或者在您的情况下,将已使用的端口映射到容器。

例如,这将适用于您的主机:

services:
    webapp:
        image: myimage
        ports:
            - '3000:3000'

    mongo:
        image: 'mongo:latest'
        ports:
            - '27018:27017'

    mongo2:
        image: mongo:latest
        ports:
            - '27019:27017'

主机 mongo 侦听 27017。主机还将端口 27018 和 27019 映射到容器 mongo 实例,都侦听容器内的 27017。

每个容器都有自己的网络命名空间,并且不知道在另一个容器或主机上运行什么。

网络

webapp 需要能够连接到 mongo 容器的内部端口。您可以通过 container network 执行此操作,它允许容器之间的连接以及每个服务的名称解析

services:
    webapp:
        image: myimage
        ports:
          - '3000:3000'
        networks:
          - myapp
        depends_on:
          - mongo

    mongo:
        image: 'mongo:latest'
        ports:
          - '27018:27017'
        networks:
          - myapp

networks:
    myapp:
        driver: bridge

然后在您的应用中,网址 mongo://mongo:27017 将起作用。

从你的主机需要使用映射的端口和主机上的地址,通常是localhost:mongo://localhost:27018

【讨论】:

感谢您的回答,但这对我仍然不起作用。我假设为一个容器放置“链接”会自动在两者之间建立一个专用网络?也许我错了。有关如何在容器内的不同端口上启动 mongo 的任何建议? 默认情况下,容器连接到 docker0 桥接器,除非您设置 links,否则不允许容器间通信。您必须修改 mongo 配置。也许创建你自己的Dockerfile FROM mongoCOPY 配置到你的新图像到build 您的答案的第一部分是正确的:“默认情况下,容器连接到 docker0 网桥”我不认为第二部分是:“除非您设置,否则不允许容器间通信链接”。实际上默认情况下它们可以,因为它们在同一个网络中。除非我对你的意思有不同的理解。 马特,你真的很接近解决我的问题,我发现你的大部分答案都是准确的,所以我给了你 +1。但是,请记住您的指南,我对我的 docker-compose 文件进行了更改,并以不同的方式运行它来解决我的问题。所以我不会接受你的作为最终答案。 @MahshidZeinaly docker0 网桥受 iptables 规则的防火墙保护,因此虽然“已连接”的容器默认无法通信。我没有意识到 v2 docker-compose 文件现在默认创建一个自定义网络,所以你不需要专门定义一个。【参考方案2】:

我遇到了同样的问题 我更改了 docker-compose.yml 文件中的端口,这对我有用 这样做时,我不会更改连接字符串中的端口

mongo:
    image: mongo
    ports:
      - "27018:27018"

【讨论】:

【参考方案3】:

在同一主机上运行的不同容器之间的默认通信

我解决了这个问题,但不是通过在不同的端口上运行容器,而是通过学习 docker-compose 版本 2 中的一项新功能,即我们不需要指定链接或网络。默认情况下,新创建的容器将成为 docker0 网络的一部分,因此它们可以相互通信。

正如Matt 提到的,我们可以在同一端口上的容器内运行进程。他们应该被隔离。所以问题不可能是docker容器和主机使用相同的端口。问题可能是试图将主机中使用的端口转发到容器中的另一个端口。

下面是一个工作的 docker-compose 文件:

version: '2'
services:
    webapp:
        image: myimage
        ports:
            - 3000:3000

    mongo:
        image: mongo:latest

我查看了 github 中的 mongo:latest docker 文件,发现他们暴露了 27017。所以我们不需要更改端口或将主机端口转发到正在运行的 mongo 容器。并且 mongo url 可以保持在同一个端口上:

monog_url = 'mongodb://mongo:27017'
client = MongoClient(monog_url, 27017)

Docker 在不同的端口上运行映像

所以上面的解决方案解决了问题,但是对于问题标题'docker run mongo image on a different port',最简单的方法就是将docker-compose改为:

version: '2'
services:
web:
    image: myimage

mongo:
    image: mongo:latest
    command: mongod --port 27018

Mongo 现在在 27018 上运行,以下 url 仍然可以在网络中访问:

monog_url = 'mongodb://mongo:27018'
client = MongoClient(monog_url, 27018)

【讨论】:

在没有其他解决方案的情况下,添加命令行对我有用。非常感谢!【参考方案4】:

您可以在配置文件中告诉 MongoDB listen on a different port,或者使用命令行参数:

services:
  mongo:
    image: 'mongo:latest'
    command: mongod --port 27018
    ports:
        - '27018:27018'

【讨论】:

这还没有解决问题。我查看了 mongo:latest 的 github 代码,它们公开了 27017 端口并运行命令 mongod。我猜他们带有 27017 的 mongod 命令在我的命令 mongod --port 27018 之前运行。你怎么看? 实际上它是我关于如何在不同端口运行 mongo 的问题的答案(尽管没有必要这样做来解决我的问题)它在端口 2718 上运行 mongo。只是不需要做端口转发 27018:27018。端口 27018 已经可以在私有网络中使用:mongo:27018

以上是关于docker 在不同的端口上运行 mongo 映像的主要内容,如果未能解决你的问题,请参考以下文章

使用 testcontainers 使用自定义端口运行 ES docker 映像

Docker:更改已创建容器上的端口绑定而不会丢失数据

使用映射端口访问 docker 容器内的 JMX

在 Amazon ECS 上运行 X-Ray 守护程序

如何在同一个 docker 映像上使用不同类型的 gpus(例如 1080Ti 与 2080Ti)而不需要重新运行“python setup.py develop”?

使用 gradle bootBuildImage 构建的 SpringBoot Docker 映像无法在 <1024 的任何端口上启动