docker - Docker 上的 Websocket 和 nginx

标签 docker go nginx websocket

我正在尝试构建一个由两部分组成的服务:后端和前端。两者都位于不同的 docker 容器上,并通过 docker-compose 配置和 nginx 容器进行通信。

对于 https 访问,一切都很好,但是当我尝试使用 websocket 时,我遇到升级错误,即使 Nginx 配置获取了此信息

错误消息:websocket:客户端未使用 websocket 协议(protocol):“连接” header 中未找到“升级” token

我在 Golang 后端使用 fasthttpfasthttp/websocket。代码在 localhost 上运行(没有 nginx 配置),但是 Docker + nginx 的组合似乎破坏了某些东西。 前端使用 react 工作,是一个简单的 let socket = new WebSocket(wss.mydomain.com/ws/uploadPicture/);

编辑:

  • upgrader.Upgrade 之前使用 ctx.Request.Header.ConnectionUpgrade() 时,结果为 true,但 ctx.Response.Header.ConnectionUpgrade() 为 false

谢谢!


Golang 后端

var upgrader = websocket.FastHTTPUpgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
    CheckOrigin: func(ctx *fasthttp.RequestCtx) bool {
        return true
    },
}
func    InitRouter() func(*fasthttp.RequestCtx) {
    router := fasthttprouter.New()

    router.GET("/ws/uploadPicture/", doWS)

    return router.Handler
}
func    doWS(ctx *fasthttp.RequestCtx) {
    err := upgrader.Upgrade(ctx, func(conn *websocket.Conn) {
        //SHOULD DO STUFF
    })
    if (err != nil) {
        logs.Error(err.Error()) //HIT THIS ERROR
        return
    }
}

...
fasthttp.ListenAndServe(`:8000`, InitRouter())

Nginx.conf

#############################################################################
## NGINX CONFIGURATION FOR THE WEBAPP
#############################################################################
upstream webapp {
    server webapp:3000;
    keepalive 4;
}
server {
    listen [::]:443 ssl;
    listen 443 ssl;

    server_name mydomain.com;

    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://webapp;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}

#############################################################################
## NGINX CONFIGURATION FOR THE PROXY
#############################################################################
upstream proxy {
    server proxy:8000;
    keepalive 4;
}
server {
    listen [::]:443 ssl;
    listen 443 ssl;

    server_name api.mydomain.com;

    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
        add_header 'Access-Control-Allow-Credentials' true;
        proxy_pass http://proxy;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}


#############################################################################
## NGINX CONFIGURATION FOR THE PROXY
#############################################################################
upstream proxyws {
    server proxy:8000;
    keepalive 4;
}
server {
    listen [::]:443 ssl;
    listen 443 ssl;

    server_name wss.mydomain.com;

    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_pass http://proxyws;
    }

}

Docker-compose

  #############################################################################
  ## IMAGE FOR THE PROXY
  #############################################################################
  proxy:
    container_name: proxy
    build: ./src/Proxy
    restart: always
    env_file: .env
    ports:
      - "8000:8000"

  #############################################################################
  ## IMAGE FOR THE WEBAPP
  #############################################################################
  webapp:
    container_name: webapp
    build: ./src/Webapp
    restart: always
    volumes:
      - ./src/Webapp:/home/app
      - /home/app/.next
      - /home/app/node_modules
    ports:
      - 3000:3000

  #############################################################################
  ## IMAGE THE NGINX & CERTBOT FOR REVERSE PROXY
  #############################################################################
  nginx: 
    image: nginx:latest
    container_name: nginx
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - 80:80
      - 443:443

最佳答案

我是 fasthttp 的 websocket 包的维护者。该问题已在 master 分支上修复。

下载:

go get github.com/fasthttp/websocket@master

请再试一次。

如果问题仍然存在,请在 https://github.com/fasthttp/websocket/issues 中打开问题

很快,我将发布新版本。

关于docker - Docker 上的 Websocket 和 nginx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60192460/

相关文章:

postgresql - 应用程序无法在 docker 中运行,无法加载文件或程序集 'System.Runtime.CompilerServices.Unsafe

docker - 如何在已经安装了Python 3.4的Docker容器中升级到Python 3.5? (我在 Ubuntu 20.04 上运行 Docker 容器)

Redis 哨兵 docker 镜像/Dockerfile

docker - 与 Rancher 的跨容器/主机通信

go - 如何将其他程序包中定义的标志合并到cobra.flags中?

c++ - Cgo 生成的源代码无法在 MVC 上编译

testing - 如何运行没有输出注释的 Go 示例?

php - 全新安装时出现 "Error in exception handler"

django - Nginx 静态文件不加载 Django

ruby-on-rails - Access-Control-Allow-Origin 不适用于 Backbone json 请求,Nginx 设置 "wide-open", header 看起来不错