Docker nginx 502 用于 GET/Post 请求但不是 websocket 的错误网关

标签 docker go nginx bad-gateway

在 stackoverflow 上有各种类似的案例,但它们几乎都引用了不正确的端口或使用 localhost 作为 IP 而不是 docker-machine ip。

vue.js 应用程序可以很好地连接到 websocket 并正常工作。但是,对 192.168.99.100:8080/meows 和其他端点的 GET 请求都命中了 nginx 502 bad gateway。手动访问端点(而不是 vue.js)也会遇到 502 bad gateway

IP 设置正确。端口在所有地方都是相同的 :8080。端点具有正确的 http 动词,并且所有端点都有一个指向 服务器位置/..{}nginx upstream。然而连接到网络没有问题,所有数据都没有问题。

编辑:我使用 docker-toolbox 运行 Windows 7,因为我的 Windows 版本没有完整的虚拟化功能。安装完成后无需进一步配置。

架构如下:

enter image description here

docker-compose

version: "3.6"

services:
  meow:
    build: "."
    command: "meow-service"
    depends_on:
      - "postgres"
      - "nats"
    environment:
      POSTGRES_DB: "meower"
      POSTGRES_USER: "meower"
      POSTGRES_PASSWORD: "123456"
      NATS_ADDRESS: "nats:4222"
  query:
    build: "."
    command: "query-service"
    depends_on:
      - "postgres"
      - "nats"
    environment:
      POSTGRES_DB: "meower"
      POSTGRES_USER: "meower"
      POSTGRES_PASSWORD: "123456"
      NATS_ADDRESS: "nats:4222"
      ELASTICSEARCH_ADDRESS: "elasticsearch:9200"
  pusher:
    build: "."
    command: "pusher-service"
    depends_on:
      - "nats"
    environment:
      NATS_ADDRESS: "nats:4222"
  postgres:
    build: "./postgres"
    restart: "always"
    environment:
      POSTGRES_DB: "meower"
      POSTGRES_USER: "meower"
      POSTGRES_PASSWORD: "123456"
  nats:
    image: "nats-streaming:0.9.2"
    restart: "always"
  elasticsearch:
    image: 'docker.elastic.co/elasticsearch/elasticsearch:6.2.3'
  nginx:
    build: "./nginx"
    ports:
      - "8080:80"
    depends_on:
      - "meow"
      - "query"
      - "pusher"

nginx.conf:

user nginx;
worker_processes 1;

events {
  worker_connections 1024;
}

http {
  upstream meows_POST {
    server meow:8080;
  }

  upstream meows_GET {
    server query:8080;
  }

  upstream search_GET {
    server query:8080;
  }

  upstream pusher {
    server pusher:8080;
  }

  server {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    add_header Access-Control-Allow-Origin *;

    location /meows {
      limit_except GET POST OPTIONS {
        deny all;
      }
      proxy_pass http://meows_$request_method;
    }

    location /search {
      limit_except GET OPTIONS {
        deny all;
      }
      proxy_pass http://search_GET;
    }

    location /pusher {
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_pass http://pusher;
    }
  }
}

并且为了表明go应用程序也使用了正确的端口,下面是监听的端口

func newRouter() (router *mux.Router) {
    router = mux.NewRouter()
    router.HandleFunc("/meows", listMeowsHandler).
        Methods("GET")
    router.HandleFunc("/search", searchMeowsHandler).
        Methods("GET")
    return
}

router := newRouter()
if err := http.ListenAndServe(":8080", router); err != nil {
    log.Fatal(err)
}

最佳答案

代替:

ports:
  - "8080"

在每个 docker-compose 服务中,尝试:

ports:
  // I assume your containers operate on 8080 port
  - "8080:8080"

通过仅指定 8080,您可以将容器的端口 8080 分配给主机的随机端口。我相信你不想要那个。您可以使用 docker-compose ps 进行验证。

另外,为什么要将所有地方的默认端口更改为 8080?使用 Docker 则没有必要,您可以简单地将端口映射到主机端的不同端口,例如:

ports:
    - "8080:80"

请记住,容器使用它们的端口相互通信,并且不需要发布这些端口。您只发布要“从外部世界”访问的端口。

关于Docker nginx 502 用于 GET/Post 请求但不是 websocket 的错误网关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56392892/

相关文章:

docker - 如何建立picadoh/motocker docker 形象?

git - 无法使用 fig/crane 在 Docker 容器中执行 git 命令

javascript - React 应用程序寻找未被访问的静态文件

amazon-web-services - 适用于Amazon AWS的Dockerfile脚本

go - 通用函数来获取 Go 中任何结构的大小

mysql - 使用 MySQL 5.6 和 GORM 的递归表中的外键约束失败

go - 在 Alexa 中,我如何在 Intent 代码中定义插槽默认值?

postgresql - 在 2019 年 10 月 31 日之前更新您的 Amazon RDS SSL/TLS 证书

nginx - 如何使用Nginx阻止引荐垃圾邮件?

docker - 在 docker 容器超时时从 s3 复制到 Redshift