当前位置: 首页 > 知识库问答 >
问题:

如何从node.js应用程序获得docker映射端口?

元英朗
2023-03-14

我想从节点内部获取映射端口。js应用程序。

前任。

docker compose

my-app:
    build:
        context: ./my-app
    ports:
        - "80"     
    volumes:
        - /var/run/docker.sock:/tmp/docker.sock
    networks:
        - private

docker ps-a

1234 my-app "/usr/local/bin/dock…"   About a minute ago   Up About a minute   0.0.0.0:33962->80/tcp

我想从node获取33962端口。js应用。

有什么想法吗?

共有3个答案

家弘业
2023-03-14

我用了一个图书馆来做这个。

解决方案:

const Docker = require( 'dockerode' );
const os = require( 'os' );

const docker = new Docker( { socketPath: '/tmp/docker.sock' } );
const container = docker.getContainer( os.hostname() );

container.inspect( function( error, data ) {
    if ( error ) {
        return null;
    }

    const mappedPort = data.NetworkSettings.Ports[ '80/tcp' ][ 0 ].HostPort
} );
茅涵映
2023-03-14

您可以使用docker端口。

docker port my-app 80

这将包括侦听器知识产权。如果你需要剥离它,你可以用外壳来做:

docker port my-app 80 | cut -f2 -d:

不幸的是,这只适用于访问docker套接字。我不建议在你的容器里安装这样的插座。

通常,大多数人通过向应用程序传递变量并控制docker compose文件中发布的端口来解决此问题。例如。:

my-app:
    build:
        context: ./my-app
    ports:
        - "8080:80"     
    environment:
        - PUBLISHED_PORT=8080
    volumes:
        - /var/run/docker.sock:/tmp/docker.sock
    networks:
        - private

然后应用程序将查看环境变量以重新配置自身。

西门经国
2023-03-14

所以第一件事是,目前,docker没有以任何直接的方式给出容器内的元数据信息

现在,当涉及开发环境而不是prod环境时,可以在容器中传递docker套接字

因此,您要做的是构建自己的元数据服务,然后让它将信息返回给容器,而不暴露docker套接字本身。

现在,要获得这些元数据,可以使用两种方法

在本例中,创建一个简单的endpoint,如/metadata/container_id,然后返回所需的数据。

此服务可以在主主机本身上运行,也可以在映射了docker套接字的容器上运行。

现在,在您的NodeJS服务中,您将获得当前的容器ID,然后使用相同的ID来调用此服务。这可以通过以下线程中列出的不同方式来完成

Docker,如何从集装箱内获取集装箱信息?

返回的数据可以限制,如果我只想暴露端口,我将只返回端口的详细信息。

这种方法的问题在于,您仍然让服务计算出自己的容器id,同时又相信它正在发送正确的容器id

为了在不传递信息的情况下获取元数据信息,我们需要确定哪个pad调用了元数据服务器

这可以通过使用源IP来识别。然后我们需要确定哪个容器属于这个IP。一旦我们有了容器ID,我们就可以返回元数据。

下面是一个简单的bash脚本,它也执行同样的操作

#!/bin/bash
CONTAINER_IP=$SOCAT_PEERADDR
CONTAINER_ID=$(docker ps -q | xargs docker inspect -f '{{.Id}}|{{range .NetworkSettings.Networks}}{{.IPAddress}}|{{end}}' | grep "|$CONTAINER_IP|" | cut -d '|' -f 1)
echo -e "HTTP/1.1 200 OK\r\nContent-Type: application/json;\r\nServer: $SOCAT_SOCKADDR:$SOCAT_SOCKPORT\r\nClient: $SOCAT_PEERADDR:$SOCAT_PEERPORT\r\nConnection: close\r\n";
METADATA=$(docker inspect -f '{{ json .NetworkSettings.Ports }}' $CONTAINER_ID)
echo $METADATA

现在要将其转换为Web服务器,我们可以使用Socat

sudo socat -T 1 TCP-L:10081,pktinfo,reuseaddr,fork EXEC:./return_metadata.sh

现在在容器中,当我们调用这个元数据服务器时

root@a9cf6dabdfb4:/# curl 192.168.33.100:10081
{"80/tcp":[{"HostIp":"0.0.0.0","HostPort":"8080"}]}

码头工人也是一样

CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                  NAMES
a9cf6dabdfb4        nginx                 "nginx -g 'daemon of…"   3 hours ago         Up 3 hours          0.0.0.0:8080->80/tcp   nginx

现在如何创建这样的元数据服务器取决于您

  • 我展示的socat方法

您还可以使用extra_hostsdocker compose中添加服务的IP。yml并像curl metaserver:10081那样进行调用

这应该是一种相当安全的方法,不会影响您的需求

 类似资料:
  • 问题内容: 我希望能够从终端中运行的node.js程序打开,创建一些内容,保存并退出,然后获取文件的内容。 我正在尝试做这样的事情: 但是,当它运行时,它只是将终端挂起。 我也尝试过,并得到相同的结果。 更新: 由于此过程是从运行readline的提示符下键入的命令启动的,因此使此过程变得复杂。我将最新版本的相关部分完全提取到了文件中。全文如下: 如上所示,它的工作方式是显示提示几秒钟,然后启动到

  • 问题内容: 我想从我的node.js应用程序ping服务器。 那可行吗? 谢谢 问题答案: 您可以用来调用系统ping命令

  • 问题内容: 我想在不同主机上的某些Docker容器中运行任务。而且我编写了一个管理器应用程序来管理容器(启动任务,停止任务,获取状态等)。容器启动后,它将向管理器发送一个http请求及其地址和端口,因此管理器将知道如何管理该容器。 由于同一主机上可能运行着多个容器,因此它们将被映射到不同的端口。要在我的经理上注册一个容器,我必须知道每个容器映射到哪个端口。 如何 在 Docker容器中获取映射的端

  • 问题内容: 在一个Node.js项目中,我试图从S3取回数据。 当我使用时,一切正常: 我的参数是: 如果将URL输出带到控制台并将其粘贴到Web浏览器中,它将下载所需的文件。 但是,如果我尝试使用,则会出现各种奇怪的行为。我相信我只是使用不正确。这是我尝试过的: 输出: 因此看来这工作正常。但是,当我在s 之一上设置断点时,我的IDE(NetBeans)会引发错误并拒绝显示数据值。尽管这可能只是

  • 问题内容: 我需要获取机器上所有打开的端口以及打开它们的应用程序的列表。我需要以编程方式获取此信息。 谢谢。 问题答案: 我希望能有一个更聪明的答案。我只是这样做(用Python编程),试图重写一个名为NetHogs的程序。我的版本在这里,特别是这里是Python中用于从中解析表的模块。如果您不是精通Python的人(请学习它),那么请看一下原始的NetHogs,它使用了C / C ++的混合(阅

  • 问题内容: 如何调试Node.js服务器应用程序? 现在,我主要使用带有以下打印语句的 警报调试 : 必须有更好的调试方法。我知道GoogleChrome浏览器有一个命令行调试器。该调试器也可用于Node.js吗? 问题答案: 节点检查器可以节省一天!从支持WebSocket的任何浏览器中使用它。断点,事件探查器,实时编码等,这真的很棒。 通过以下方式安装: 然后运行: