更新
我发现,如果我使用 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 配置有关。我可以向/发出请求,但对/user 的任何请求都会导致间歇性问题。
当我没有收到 504 时, Node 应用程序运行良好并创建/返回用户。我还可以使用 mongo-express 很好地连接到数据库,这样应该有助于缩小范围。
docker-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';
}
}
}
感谢任何帮助,谢谢。
最佳答案
我发现了几个类似的相关问题,并将尝试从中编译出两个可能的解决方案:
- https://serverfault.com/questions/240476/how-to-force-nginx-to-resolve-dns-of-a-dynamic-hostname-everytime-when-doing-p
- Docker Network Nginx Resolver
第一个解决方案
第一个解决方案是反转服务之间的依赖关系:您可以将 gateway
依赖于用户,而不是 poker_user
依赖于 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 解析。这需要在 nginx
和 luckily there's one 中配置解析器使用用户定义的网络时内置于 Docker 中。
这是一个 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';
}
}
}
希望这有帮助!
关于javascript - 使用 Nodejs + docker 来自 nginx 反向代理的 504 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55315958/