0

我使用nginx-proxy作为 Web 服务器中容器的反向代理。我有一个带有 Vue 前端的 Laravel 后端应用程序,它们使用Laravel Websockets通过 Websockets 进行通信。

通过 HTTP 在后端和前端容器之间本地通信工作正常,但我无法通过 HTTPS 在 Web 服务器中使用它。

我使用acme-companion来生成和更新 Let's encrypt 证书。该/etc/nginx/conf.d/default.conf文件是按照Laravel Websockets 的这些说明进行编辑的,以便与 nginx 反向代理一起使用。

在前端,我正在调用 WebSocket 服务器wss://api.domain.com。据我了解,这将到达我的location @ws并被代理到api端口 6001 中的容器(从上游复制 IP),这是我的 WebSocket 服务器侦听的。问题是没有请求到达 WebSocket 服务器。我在编辑后重新加载了 Nginx 配置nginx -s reload

有人能帮我吗?我似乎无法理解我做错了什么或如何正确调试它,因为/var/log/nginx/access.log容器/var/log/nginx/error.log内部nginx-proxy是空的。谢谢你。

docker-compose.yml

version: '2'

services:

  nginx-proxy:
    container_name: nginx-proxy
    image: jwilder/nginx-proxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/etc/nginx/vhost.d"
      - "/usr/share/nginx/html"
      - "/var/run/docker.sock:/tmp/docker.sock:ro"
      - "/etc/nginx/certs"

  letsencrypt-nginx-proxy-companion:
    container_name: letsencrypt-nginx-proxy-companion
    image: jrcs/letsencrypt-nginx-proxy-companion
    restart: always
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    volumes_from:
      - "nginx-proxy"

  api:
    container_name: api
    image: guizo/docker-laravel:php8.0-apache-postgres
    ports:
        - 6001:6001
    working_dir: /var/www/html
    volumes:
      - ./api:/var/www/html
    volumes_from:
      - "nginx-proxy"
    environment:
      VIRTUAL_HOST: api.domain.com
      LETSENCRYPT_HOST: api.domain.com

  app:
    container_name: app
    image: guizo/docker-nginx
    working_dir: /usr/share/nginx/html
    volumes:
      - ./app/dist:/usr/share/nginx/html
    environment:
      VIRTUAL_HOST: app.domain.com
      LETSENCRYPT_HOST: app.domain.com

/etc/nginx/conf.d/default.conf

map $http_upgrade $type {
  default "web";
  websocket "ws";
}
# api.domain.com
upstream api.domain.com-upstream {
    ## Can be connected with "dev_default" network
    # api
    server 172.18.0.4:80;
    # Fallback entry
    server 127.0.0.1 down;
}
server {
    server_name api.domain.com;
    listen 80 ;
    access_log /var/log/nginx/access.log vhost;
    # Do not HTTPS redirect Let'sEncrypt ACME challenge
    location ^~ /.well-known/acme-challenge/ {
        auth_basic off;
        auth_request off;
        allow all;
        root /usr/share/nginx/html;
        try_files $uri =404;
        break;
    }
    location / {
        return 301 https://$host$request_uri;
    }
}
server {
    server_name api.domain.com;
    listen 443 ssl http2 ;
    access_log /var/log/nginx/access.log vhost;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_certificate /etc/nginx/certs/api.domain.com.crt;
    ssl_certificate_key /etc/nginx/certs/api.domain.com.key;
    ssl_dhparam /etc/nginx/certs/api.domain.com.dhparam.pem;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/certs/api.domain.com.chain.pem;
    add_header Strict-Transport-Security "max-age=31536000" always;
    include /etc/nginx/vhost.d/default;
    location / {
        try_files /nonexistent @$type;
    }
    location @web {
        proxy_pass http://api.domain.com-upstream;
    }
    location @ws  {
        proxy_pass             http://172.18.0.4:6001;
        proxy_set_header Host  $host;
        proxy_read_timeout     60;
        proxy_connect_timeout  60;
        proxy_redirect         off;

        # Allow the use of websockets
        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;
    }
}
4

0 回答 0