来自节点js + docker的nginx反向代理的504响应

问题描述 投票:0回答:1

UPDATE

我发现如果我用docker exec -it backend_gateway_1 nginx -s reload重新启动容器上的nginx它会起作用。我从this question找到了一些信息。似乎连接到127.0.0.1而不是localhost可以工作,但是我使用的是docker网络所以我不确定我的情况会是什么。

原始问题

我试图使用nginx作为docker的反向代理。我无法弄清楚什么是错的,因为有时它会起作用但是如果我使用docker-compose down && docker-compose up重新启动它,那么我通常会得到这504错误

我有一种感觉这与nginx或docker配置有关。我可以向/ fine发出请求,但对/ user的任何请求都会导致间歇性问题。

当我没有收到504时,节点应用程序运行良好并创建/返回用户。我也可以使用mongo-express连接数据库,这样可以帮助缩小范围。

泊坞窗,compose.yml

version: '3.5'
services:
  gateway:
    image: nginx:latest
    restart: always
    ports:
      - 8080:80
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/nginx-error.log:/var/log/nginx/error.log
    networks:
      - poker_network
  poker_mongo:
    image: mongo:latest
    container_name: poker_mongo
    restart: unless-stopped
    volumes:
      - db-data:/data/db
    expose: 
      - "27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: test
      MONGO_INITDB_ROOT_PASSWORD: 123
    networks:
      - poker_network
    depends_on:
      - gateway
  poker_user:
    container_name: poker_user
    build: ./user/
    image: poker/user:latest
    volumes:
      - ./user/:/usr/src/app
      #- /usr/src/app/node_modules
    expose:
      - "8080"
    depends_on:
      - gateway
      - poker_mongo
    networks:
      - poker_network
    environment:
      WAIT_HOSTS: poker_mongo:27017
  mongo-express:
    container_name: mongo-express
    image: mongo-express
    restart: always
    ports:
      - 8085:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: test
      ME_CONFIG_MONGODB_ADMINPASSWORD: 123
      ME_CONFIG_MONGODB_SERVER: poker_mongo
    depends_on:
     - gateway
     - poker_mongo
    networks:
      - poker_network

networks:
  poker_network:
volumes: 
  db-data:

nginx.conf

events { worker_connections 1024; }

http {

    server {
        listen 80;
        location /user {
            rewrite /user/(.*) /$1  break;
            proxy_pass http://poker_user:8080/;
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
        }
        location / {
            return 200 'hello';
        }

    }
}

任何帮助表示赞赏,谢谢。

javascript node.js docker nginx docker-compose
1个回答
1
投票

我发现了几个类似的相关问题,并将尝试编译两个可能的解决方案:

第一解决方案

第一个解决方案是逆转服务之间的依赖关系:而不是poker_user依赖于gateway你可以gateway依赖于用户。这样当gateway启动时,如果能够解析poker_user主机名。

在这种情况下,Dockerfile看起来会这样:

version: '3.5'
services:
  gateway:
    image: nginx:latest
    restart: always
    ports:
      - 8080:80
    depends_on: poker_user
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/nginx-error.log:/var/log/nginx/error.log
    networks:
      - poker_network
  poker_mongo:
    image: mongo:latest
    container_name: poker_mongo
    restart: unless-stopped
    volumes:
      - db-data:/data/db
    expose: 
      - "27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: test
      MONGO_INITDB_ROOT_PASSWORD: 123
    networks:
      - poker_network
  poker_user:
    container_name: poker_user
    build: ./user/
    image: poker/user:latest
    volumes:
      - ./user/:/usr/src/app
      #- /usr/src/app/node_modules
    expose:
      - "8080"
    depends_on:
      - poker_mongo
    networks:
      - poker_network
    environment:
      WAIT_HOSTS: poker_mongo:27017
  mongo-express:
    container_name: mongo-express
    image: mongo-express
    restart: always
    ports:
      - 8085:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: test
      ME_CONFIG_MONGODB_ADMINPASSWORD: 123
      ME_CONFIG_MONGODB_SERVER: poker_mongo
    depends_on:
     - gateway
    networks:
      - poker_network

networks:
  poker_network:
volumes: 
  db-data:

我还删除了一些其他依赖项,因为我认为它们是多余的。

二解决方案

此解决方案基于更改nginx配置。看起来nginx试图解决proxy_pass中预先指定的主机名,因为当nginx启动它时它不可用它将继续响应504,因为它不会再尝试解决它。

proxy_pass指令中使用变量似乎有一种解决方法,这些变量被区别对待并强制nginx再次执行DNS解析。这需要在使用用户定义的网络时在Docker内置nginxluckily there's one中配置解析器。

这是一个示例nginx配置(虽然我自己没有测试过):

events { worker_connections 1024; }

http {

    server {
        listen 80;
        location /user {
            # Docker DNS server in user-defined networks
            # https://docs.docker.com/v17.09/engine/userguide/networking/configure-dns/
            resolver 127.0.0.11 ipv6=off;

            rewrite /user/(.*) /$1  break;

            # Using a variable will force nginx to re-resolve DNS name
            # https://serverfault.com/a/593003
            set $backend "http://poker_user:8080/";
            proxy_pass $backend;

            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
        }
        location / {
            return 200 'hello';
        }

    }
}

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.