(未知 url)的 Http 失败响应 - Angular 通用 Docker

Http failure response for (unknown url) - Angular Universal on Docker

我有以下设置:

docker-compose.yml中的四个服务:my_nginxmy_clientmy_apimy_db.

  1. 我使用 my_nginx 作为代理通行证到达 my_client:8000my_api:8001 (都是Node.js)。
  2. my_client 是具有服务器端的 Angular 应用程序 渲染。
  3. my_api 是一个节点应用程序,它从 my_db.
  4. 获取数据

然后,在我的 windows hosts 文件中,我的主机名与我在 my_nginx 配置服务器块中定义的主机名相同:

`127.0.0.1 my-app.local api.my-app.local`

因此可以通过主机名访问它们。

接下来,在我的 angular 应用程序中,我在每个环境文件中定义了 api url,因此对于本地开发环境,它是 http://api.my-app.local

当 api 请求来自浏览器时,它工作得很好。但是当服务器端发起请求时,从 my_client 容器,我得到一个很长(很多行)的错误,但是它的要点(以及我可以通过搜索 [=123 找到它的常用文本=]) 是:message: 'Http failure response for (unknown url): 0 Unknown Error'。但是,我能找到的其他问题并没有回答我的问题。它们要么不是服务器呈现的,要么提到了 CORS 或无法访问互联网的容器。

我确实允许来自我的 api 的任何客户端:res.setHeader('Access-Control-Allow-Origin', '*');,CORS 不是问题。此外,如果我将 http://api.my-app.local 替换为 http://some-real-website.com,那么请求会成功,它会通过,我只是没有收到适当的数据,因为它不是我的 api,但关键是我的容器能够访问互联网。跳入 my_client 容器和 ping api.my-app.local 工作(显示 127.0.0.1,不知道这是否意味着什么)。我不知道为什么会这样,虽然用 http://... ping 不行,但我不能在我的 Angular 应用程序中用 api.my-app.local 替换 http://api.my-app.local,因为那样的话会向自己发出请求,例如:http://my-app.local/api.my-app.local.

最后,如果我 ping http://api.my-app.local 然后我得到 unknown host。不知道为什么,就容器而言,http://api.my-app.local在互联网上,对吧?。我的意思是,无论 who/what/where 是否尝试访问,我都希望一切都一样,例如:

  1. someone/something 访问 url http://api.my-app.local(可以是 me/browser,可以是容器,随便)
  2. 最后,它被主机捕获(在我的例子中是 Windows),hosts 文件将它重定向到 127.0.0.1
  3. 然后到达 my_nginx 容器
  4. 识别服务器名称api.my-app.local
  5. 并将其代理到 my_api 容器。

应该很简单

编辑:

Docker 版本:17.12.0-ce-win47 (15139) 稳定

docker-compose.yml:

version: '3.4'

services:
  my_nginx:
    container_name: my_nginx
    build:
      context: ./nginx
    image: my_nginx
    ports:
      - '80:80'
      - '443:443' # SSL (not used on 'my-app.local')
    links:
      - my_api
      - my_client

  my_api:
    container_name: my_api
    build:
      context: ./node_api
    image: my_api
    ports:
      - '8001:8001'
    volumes:
      - ./node_api/app:/var/www/api.my-app.com
      - /var/www/api.my-app.com/node_modules
    links:
      - my_db
    depends_on:
      - my_db
    networks:
      default:
        aliases:
          - api.my-app.local
    tty: true
    # command: ["pm2-docker", "pm2.config.json"] < moved to Dockerfile

  my_client:
    container_name: my_client
    build:
      context: ./node_client
    image: my_client
    ports:
      - '8000:8000'
    volumes:
      - ./node_client/app:/var/www/my-app.com
      - /var/www/my-app.com/node_modules # Inside the container, use the node_modules installed there.
    links:
      - my_api
    tty: true
    command: ["pm2-docker", "pm2.config.json"]

  my_db:
    container_name: my_db
    build:
      context: ./mysql
    image: my_db
    restart: always
    ports:
      - '3306:3306'
    volumes:
      - './_space/mysql:/var/lib/mysql'

Nginx 配置api 服务器块:

server {
    listen 80;
    server_name api.my-app.local;

    charset     utf-8;
    client_max_body_size 4096M;

    location / {
        proxy_pass http://my_api:8001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    location ~ /\.ht {
        deny all;
    }
}

当然,除了 server_nameproxy_pass 指令外,客户端的也是一样的。我不知道 proxy_http_versionproxy_set_headerproxy_cache_bypass 是干什么用的,我只是从在线示例中复制了配置。

在您的 docker-compose.yml 中,您需要声明 my_nginx 的别名和 my_client 的 link:

my_nginx:
    networks:
        default:
            aliases:
                - api.my-app.local

my_client:
    links:
        - my_nginx