我有两个容器应用程序和网络服务器。Web服务器是普通的nginx:alpine图像,应用程序是在ubuntu:focal下的端口3030上运行的expressjs应用程序。我听说这是为应用程序和服务器使用单独的容器的常见做法。所以我添加proxy_pass http://app:3030/;到 nginx 配置中。出了点问题,我对此进行了深入研究。为了排除不正确的 nginx 设置,我检查了从网络服务器到应用程序容器的原始卷曲请求,但没有成功。这是我的 docker-compose:
version: '3.5'
services:
webserver:
image: nginx:alpine
env_file: .env
restart: always
tty: true
ports:
- ${NGINX_HOST_HTTP_PORT}:80
- ${NGINX_HOST_HTTPS_PORT}:443
volumes:
- ${APP_CODE_PATH_HOST}:${APP_DIR}
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/sites/:/etc/nginx/conf.d/
- ./nginx/ssl/:/etc/ssl/
depends_on:
- app
container_name: ${CONTAINER_NAME_PREFIX}-webserver
networks:
- app-network
app:
env_file: .env
restart: on-failure
tty: true
build:
dockerfile: ./docker/app/Dockerfile
args:
APP_ENV: ${APP_ENV}
APP_DIR: ${APP_DIR}
PRODUCT_ID: ${PRODUCT_ID}
context: ../
environment:
- DEBIAN_FRONTEND=noninteractive
container_name: ${CONTAINER_NAME_PREFIX}-app
networks:
- app-network
networks:
app-network:
driver: bridge
Run Code Online (Sandbox Code Playgroud)
我可以从应用程序容器 CLI 请求 Express:
/ # curl -X GET http://127.0.0.1:3030/multichannel/4034?uid=a6O5iTje8sR2PESbWpAM
{"status": "OK"}
Run Code Online (Sandbox Code Playgroud)
现在从网络服务器:
/ # ping app
PING app (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.090 ms
/ # curl -X GET http://172.19.0.2:3030/multichannel/4034?uid=a6O5iTje8sR2PESbWpAM
curl: (7) Failed to connect to 172.19.0.2 port 3030 after 0 ms: Connection refused
/ # curl -X GET http://app:3030/multichannel/4034?uid=a6O5iTje8sR2PESbWpAM
curl: (7) Failed to connect to app port 3030 after 0 ms: Connection refused
Run Code Online (Sandbox Code Playgroud)
Nginx 日志(不要关注 IP,它是正确的,容器重建后它发生了变化):
2021/10/29 15:40:46 [error] 24#24: *12 connect() failed (111: Connection refused) while connecting to upstream, client: 172.20.0.1, server: api.test, request: "GET /multichannel/4034?uid=a6O5iTje8sR2PESbWpAM HTTP/1.1", upstream: "http://172.20.0.3:3030/multichannel/4034?uid=a6O5iTje8sR2PESbWpAM", host: "api.test"
Run Code Online (Sandbox Code Playgroud)
当然Nginx的conf有:
location / {
proxy_pass http://app:3030;
}
Run Code Online (Sandbox Code Playgroud)
为什么连接被拒绝?两个容器都在同一个网络中
终于找到无法连接的原因了。当 @devatherock 提到时,ARTIFACTORY_URL=http://localhost:8081我检查了使用的主机上的应用程序代码,发现了这一点:
server.listen(3030, "127.0.0.1", () => {
logger.debug(`Server is running on ${serverConfig.port} port`);
});
Run Code Online (Sandbox Code Playgroud)
然后我尝试“localhost”作为主机,但仍然得到 502。所以是时候阅读文档了。Expressjs 的server.listen工作方式类似于 Nodejs server.listen https://nodejs.org/api/net.html#serverlistenport-host-backlog-callback
如果省略 host,则当 IPv6 可用时,服务器将接受未指定的 IPv6 地址 (::) 上的连接,否则接受未指定的 IPv4 地址 (0.0.0.0) 上的连接。在大多数操作系统中,侦听未指定的 IPv6 地址 (::) 可能会导致 net.Server 也侦听未指定的 IPv4 地址 (0.0.0.0)。
答案是使用“0.0.0.0”或省略主机参数。127.0.0.1 或 localhost 只能在本地计算机上访问,因为它绑定到环回接口。
| 归档时间: |
|
| 查看次数: |
1312 次 |
| 最近记录: |