应用程序在客户端容器内向服务器容器发出的请求不起作用。

huangapple go评论72阅读模式
英文:

Request from the application inside the client container to the server container is not working

问题

在我的React应用程序和具有数据库的服务器上,我发出了如下请求:

fetch('http://serverstrapi:1337/api/auth/local/register/')  fetch('http://serverstrapi/api/auth/local/register/')

但是我看到以下错误消息:

应用程序在客户端容器内向服务器容器发出的请求不起作用。

然而,如果我通过 exec 访问客户端容器并执行 ping 'serverstrapi',这是成功的。另外,如果我将 'serverstrapi' 更改为 'localhost:3001',一切正常,外部地址也有效。

这是 docker-compose 文件:

version: '3'
services:
  client:
    build:
      context: ./client
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=development
      - SERVER_PORT=1337
    volumes:
      - ./client:/app
    ports:
      - 8081:3000

  serverstrapi:
    build:
      context: ./server
      dockerfile: Dockerfile
    volumes:
      - ./server/config:/server/config
      - ./server/src:/server/src
      - ./server/package.json:/server/package.json
      - ./server/yarn.lock:/server/yarn.lock
      - ./server/.env:/server/.env
      - ./server/public/uploads:/server/public/uploads
    ports:
      - 3001:1337
    environment:
      - NODE_ENV=development
    depends_on:
      - db

  db:
    image: postgres
    restart: always
    env_file:
      - .env
    ports:
      - 4001:5432
    volumes:
      - ./db-data:/var/lib/postgresql/data

  adminer:
    image: adminer
    restart: always
    ports:
      - 5001:8080

  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 80:80
    depends_on:
      - client
      - serverstrapi

我尝试过完全从 docker-compose 文件中删除 Nginx 并删除所有网络和容器以重新开始。我还尝试过各种 'serverstrapi' 地址的变化,包括带端口和不带端口等。

我会感激任何建议。

英文:

I have a React application and a server with a database. In the application, I make a request like fetch('http://serverstrapi:1337/api/auth/local/register/') or fetch('http://serverstrapi/api/auth/local/register/') and I see:

应用程序在客户端容器内向服务器容器发出的请求不起作用。

However, if I access the client container by exec and perform a ping 'serverstrapi', it is successful. Additionally, if I change 'serverstrapi' to 'localhost:3001', everything works fine, the external address works.

Here is the docker-compose:

version: '3'
services:
  client:
    build:
      context: ./client
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=development
      - SERVER_PORT=1337
    volumes:
      - ./client:/app
    ports:
      - 8081:3000

  serverstrapi:
    build:
      context: ./server
      dockerfile: Dockerfile
    volumes:
      - ./server/config:/server/config
      - ./server/src:/server/src
      - ./server/package.json:/server/package.json
      - ./server/yarn.lock:/server/yarn.lock
      - ./server/.env:/server/.env
      - ./server/public/uploads:/server/public/uploads
    ports:
      - 3001:1337
    environment:
      - NODE_ENV=development
    depends_on:
      - db

  db:
    image: postgres
    restart: always
    env_file:
      - .env
    ports:
      - 4001:5432
    volumes:
      - ./db-data:/var/lib/postgresql/data

  adminer:
    image: adminer
    restart: always
    ports:
      - 5001:8080

  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 80:80
    depends_on:
      - client
      - serverstrapi

I have tried removing Nginx completely from the docker-compose file and deleting all networks and containers to start fresh. I have also tried various variations of the 'serverstrapi' address, such as with a port and without a port, etc.

I would appreciate any suggestions.

答案1

得分: 1

看起来你遇到了一个问题,这是因为Docker网络和Web浏览器交互的方式导致的。

当你从浏览器访问由客户端容器提供的静态页面时,浏览器会检索静态文件,然后尝试执行API调用。问题出现在这里,因为你的浏览器不是Docker网络的一部分,而服务器容器正在其中运行。因此,它无法将容器名称(或主机名)解析为IP地址。

在Docker中,容器名称在同一Docker网络中可以解析为它们各自的IP地址。然而,这种名称解析在Docker网络环境之外是不可访问的,这就是为什么你的浏览器无法将主机名或容器名称解析为IP的原因。

为了访问服务器容器的API,你需要使用Docker运行的机器的IP地址(假设你已经暴露了必要的端口),或者已经适当配置以指向该IP的域名。

请记住,你的客户端代码(如在浏览器中运行的JavaScript)在Docker环境之外执行,因此它无法访问Docker内部的DNS。它需要访问的任何API端点必须在其运行的网络环境内可访达,通常是公共互联网,如果它是一个Web应用程序的话。

解决方案是将服务器API的主机名/IP和端口作为环境变量传递给你的React应用容器,并将服务器API的URL修改为传递的环境变量。

英文:

It seems like you're encountering an issue due to the way Docker networking and web browsers interact.

When you access the static page served by the client container from your browser, your browser retrieves the static files and then tries to execute the API calls. The problem arises because your browser is not part of the Docker network where the server container is running. Therefore, it cannot resolve the container name (or hostname) to an IP address.

In Docker, container names are resolvable to their respective IP addresses within the same Docker network. However, this name resolution is not accessible outside of the Docker network environment, which is why your browser can't resolve the hostname or container name to an IP.

In order to access your server container's API, you'll need to use either the IP address of the machine where Docker is running (assuming you've exposed the necessary ports) or a domain name that has been appropriately configured to point to that IP.

Remember, your client-side code (like JavaScript running in a browser) executes outside of the Docker environment, so it doesn't have access to the Docker internal DNS. Any API endpoints it needs to access must be reachable within the context of the network it's running on, typically the public internet if it's a web application.

Solution would be to pass the server api hostname/ip and port as environment variable to your react app container and you modify the url of the server api to the environment variables passed.

huangapple
  • 本文由 发表于 2023年5月24日 19:34:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76323091.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定