我们如何从主机服务器向 docker 容器内的端点发出 http 请求

问题描述 投票:0回答:1

我想从当前在 localhost 上运行的服务器向正在运行的容器内的 api 端点发出 http 请求。我无法使用端口映射,因为我正在创建多个容器,每个请求一个容器。

这就是我的代码的样子 我正在为每个请求使用 dockerode 创建、运行、停止和删除容器。 容器创建和运行成功,但 axios 请求超时。 有什么解决办法吗?

 const data = await request.json();
    const { language, program, inputs } = data;
    const docker = new Docker();
    const containerId = v4();
    // 1. I am trying to spin new container using dockerode on each request
    const container = await docker.createContainer({
      Image: "project-name",
      name: containerId,
    });
    await container.start();
    const containerInfo = await container.inspect();
    const ipAddress = containerInfo.NetworkSettings.IPAddress;
    const containerUrl = `http://${ipAdress}/api/run`;
    // 2 .Send code as input to that container's api/run endpoint (Where compiler logic is)

    const response = await axios.post(containerUrl, data);
    // 3. Then stop and remove after getting output
    await container.stop();
    await container.remove();

node.js docker next.js13 docker-container dockerode
1个回答
0
投票

除非在一个非常特定的主机设置中,否则您无法访问容器专用 IP 地址。您需要发布一个端口,并且需要通过其发布的端口来访问容器。但是,您不必自己选择端口;您可以选择端口。如果您不分配端口,那么 Docker 将自行选择一个未使用的端口。 (在

docker run
语法中,这相当于
docker run -p 12345
只有容器端口号而没有其他内容。)

docker.createContainer({
  Image: "project-name",
  Name: containerId,
  HostConfig: {
    PortBindings: {
      "80/tcp": [ {} ]
    }
  }
});

现在当您检查容器时,

PortBindings
值将被填充。

const containerInfo = await container.inspect();
const host = 'localhost'; // but see below
const port = containerInfo.HostConfig.PortBindings['80/tcp'][0].HostPort;
const containerUrl = `http://${host}:${port}/api/run`;

host
值更难以编程方式确定。如果您的应用程序在本机 Linux 主机上的普通 Docker 上运行,或者在 Docker 桌面上运行,那么
localhost
是正确的。如果此应用程序本身在可以访问主机 Docker 套接字的容器内运行,则您将需要
host.docker.internal
或类似的值。我通常在日常工作中使用 Minikube VM,它的
minikube ip
地址正是我所需要的。您还可以设置使用远程 Docker 守护进程,并且主机名将完全是其他名称。

正如评论所暗示的那样,我可能会重新考虑这种方法。每个请求启动一个容器实际上有点昂贵,需要考虑很多生命周期问题(如果主进程崩溃,容器会发生什么),并且启动容器意味着对主机的根级别访问不受限制。我还在上一段中暗示了一些特定于环境的差异,并且此代码根本无法在 Kubernetes 等非 Docker 容器环境中运行。如果您可以设置一个长期运行的服务器并向其发出 HTTP 请求,它将更易于维护(并且更容易实际运行)。

© www.soinside.com 2019 - 2024. All rights reserved.