【问题标题】:when running nodejs angular app in docker it is returning failed在 docker 中运行 nodejs angular 应用程序时返回失败
【发布时间】:2022-10-25 12:54:42
【问题描述】:

我正在尝试通过一个简单的项目为 docker 设置 poc。它包括 angular、express、nodejs 和 mongodb atlas。

角度在 4200 和 nodejs 3000 上运行

https://github.com/changan1111/UserManagement

它在本地相同的设置中工作正常..

当我去码头工人?

我看到节点 js 已启动并正在运行。

当我看到文件列表时,我看到一切都很好。

当我去 http://localhost/user 它返回值

但是当我从浏览器读取值时,它显示

我尝试了一些解决方案,但所有解决方案都返回失败的相同响应。这有什么问题..任何人都可以看看这个,让我知道设置有什么问题。

app.use(cors());

/*
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "req.headers.origin"); // update to match the domain you will make the request from
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.header("Access-Control-Allow-Methods", "DELETE,PUT,GET,POST");

  next();
});*/


/*
app.use(cors({
  "origin": ['http://localhost:3000'],
  "methods": "GET,PUT,POST",
  "preflightContinue": false,
   "credentials": true
}));*/

也尝试使用 IP 地址http://192.168.0.103/,但没有变化 Dockerfile:

【问题讨论】:

  • 首先,您必须在 Dockerfile 中将 EXPOSE 放在 CMD 之前
  • 那是复制粘贴错误。在 CMD 之前给出 EXPOSE
  • 请用真实代码替换代码图像。
  • 在您的浏览器中,您调用的是localhost:3000/user 而不是localhost/user。而您的问题是,您的应用程序可以通过80 而不是3000 访问?
  • 您的映射端口(您可以尝试从外部访问的端口)是否与暴露的端口匹配?通常你会想要在运行一个暴露了一些端口的容器时指定端口。

标签: node.js angular docker


【解决方案1】:

您的问题尚不清楚,但根据您提供的图片,如果您的 Angular 应用程序似乎无法在127.0.0.1 中访问您的 Express 后端。

您将 http://localhost:3000 配置为您的 API 端点,但请注意,从 Docker 的角度来看,localhost 指的是容器本身,并且可能与您的实际主机不同。

要解决此问题,您可以使用0.0.0.0Express 指示它应该在每个网络接口中使用listen

app.listen(3000, '0.0.0.0', () => {
  console.log("listening on PORT verify: 3000");
});

nodejs guide documentation 也举例说明了该解决方案。

另外,请尝试将您的environment文件中的Url变量调整为地址http://localhost,不注明端口,即使用端口80:根据您在Github中的存储库中上传的代码应用程序似乎侦听端口3000,但在您的屏幕截图中,您肯定使用端口80。这背后的原因是,如果 express 同时为您的 Angular SPA 和 API 提供服务,并且您可以分别使用 http://localhost/readhttp://localhost/user 从主机联系这两件事,那么可能会调整您 Url按照建议将变量设置为http://localhost 可以解决问题。

【讨论】:

  • 我改变了 app.listen(3000, '0.0.0.0', () => { console.log("listening on PORT verify: 3000"); });但我仍然没有看到行为上有任何差异
  • 容器 ID 图像命令创建的状态端口名称 731365201d70 106d “节点服务器” 8 分钟前 8 分钟前 0.0.0.0:80->3000/tcp crancy_pasteur 我尝试了 localhost 并使用浏览器中主机的 ip(# 由 Docker Desktop 192.168 添加.0.106 host.docker.internal 192.168.0.106 gateway.docker.internal)
  • 你能告诉我任何其他需要的细节吗?
  • 嗨@ChanGan。我很遗憾听到它不能正常工作。你还在面对同样的问题吗?完全一样的问题?由于您同时使用 Express Angular 输出和 API,您可以尝试在 apiservice.service 中使用相对路由。我的意思是,环境变量Url 可以在您的环境中定义为一个空字符串。也许这种替代方法可能会有所帮助。理想情况下,您的 SPA 应该由某种 Web 服务器提供服务,例如 nginx。该服务器可能会代理针对您的 API 发出的请求。我不确定是否为此目的使用 Express
  • 最初我尝试使用 url:"/" 将其从源地址获取基本 url。但这在请求中是空的。 http:///user .. 源没有被添加到请求中。但它应该作为 http://{requestedip}/user.. 因为这是空的 3 个斜杠
【解决方案2】:

您在运行容器时是否尝试过像这样公开端口?

docker run -p 4000:4000 container_name(假设这里是 Linux 主机)

要不就

docker run --network="host" container_name 也许?

然后通过 localhost:4000 从 Docker 内部或外部的任何服务访问。

通过这种方式,容器的内部 localhost 将与您的实际主机的 localhost 匹配。 这有一些缺点,但我假设你没有在生产环境中运行它,所以它应该不是很重要。

目前尚不清楚您是否尝试从 Docker 外部访问您的 Dockerized 应用程序。您的后端和前端是否共享同一个容器?它们都是容器化的吗?

EXPOSE 只允许 Docker 的内部应用程序找到该端口 IIRC。

您需要指定要向主机公开的端口。

【讨论】:

  • 他通过 docker-compose 暴露了端口。
  • @akop 我的错。一定错过了,还没有深入研究回购。先前的答案提到主机和容器locahost 端口之间的混淆是一个潜在问题,所以我认为将它们完全匹配可能会减少那里混淆的机会(如果 OP 还没有这样做的话)。
【解决方案3】:

我在本地运行你的代码并且运行良好,我在 Docker 上运行它也很好。因此,对于我在 cmets 和日志屏幕截图中所读到的内容,错误实际上在于您部署应用程序的方式。当您运行 docker run p 80:3000 -it {imageName} 时,您将端口 3000 发布到主机的端口 80,这意味着您的前端只能从端口 80 访问 /user,因为 3000 仅在 Docker 中退出。 Check out the docs on published ports。我希望这很清楚。

您的问题的解决方案是更新前端environment.prod.ts

export const environment = {
  production: true,
  Url:'http://{ip.of.the.hosting.machine}:{publishedPort}'
};

旁注:如果您使用 80 作为发布的端口,您可以在 environment.prod.ts 中省略它,因为 http://192.168.0.1:80 == http://192.168.0.1

【讨论】:

    猜你喜欢
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 2022-12-04
    • 2017-10-15
    • 2016-04-19
    • 1970-01-01
    • 2020-06-24
    相关资源
    最近更新 更多