Socket.io 使用 Docker 部署 MERN 应用程序时 NGINX 出错
Socket.io error with NGINX when deploying a MERN app with Docker
我使用 docker 在 digitalocean 上部署了一个 MERN 应用程序。后端和前端看起来不错,但由于某种原因,Websocket socket.io 连接在已部署的应用程序上失败。
错误信息:
我使用 http-proxy-middleware,我的 setupProxy.js 文件:(main-be是容器的名称)
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://main-be:5001',
changeOrigin: true,
})
);
};
frontend/src/utils/axios.js:
import axios from 'axios';
export const baseURL = 'https://example.com';
export default axios.create({ baseURL });
frontend/src/utils/constants.js:
const API_BASE_ORIGIN = 'wss://46.111.119.161';
export { API_BASE_ORIGIN };
...我在这里尝试了这些,但 none 有效:
const API_BASE_ORIGIN = 'https://example.com';
const API_BASE_ORIGIN = 'ws://46.111.119.161:5001';
const API_BASE_ORIGIN = 'ws://46.111.119.161';
const API_BASE_ORIGIN = 'wss://46.111.119.161';
const API_BASE_ORIGIN = 'wss://46.111.119.161:5001';
部分socketContext.js:
//* socket connection
useEffect(() => {
const newSocket = socketIo.connect(API_BASE_ORIGIN, {
transports: ['websocket'],
});
setSocket(newSocket);
if (!newSocket) return;
newSocket.on('connect', () => {
console.log(`Hurrah Socket ${newSocket.id} Connected`);
});
}, []);
NGINX default.conf 配置文件:
upstream api {
server main-be:5001;
}
upstream client {
server main-fe:3000;
}
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://$host$request_uri;
}
# main server block
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
# enable subfolder method reverse proxy confs
include /config/nginx/proxy-confs/*.subfolder.conf;
# all ssl related config moved to ssl.conf
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / {
proxy_pass http://client;
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;
}
location /api {
proxy_pass http://api;
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;
}
location /ws/ {
proxy_pass http://client;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
}
解决方案:
将 WDS_SOCKET_PORT=0
添加到 React 前端 .env 文件。 (所以它不会添加不必要的额外端口)
将 nginx default.conf 配置文件编辑为这个(不是整个文件):
location /socket.io {
proxy_pass http://api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host; }
setupProxy.js 文件:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://main-be:5001',
changeOrigin: true,
})
);
};
frontend/src/utils/axios.js:
import axios from 'axios';
export const baseURL = 'https://example.com';
export default axios.create({ baseURL });
frontend/src/utils/constants.js:
const API_BASE_ORIGIN = 'https://example.com';
export { API_BASE_ORIGIN };
我使用 docker 在 digitalocean 上部署了一个 MERN 应用程序。后端和前端看起来不错,但由于某种原因,Websocket socket.io 连接在已部署的应用程序上失败。
错误信息:
我使用 http-proxy-middleware,我的 setupProxy.js 文件:(main-be是容器的名称)
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://main-be:5001',
changeOrigin: true,
})
);
};
frontend/src/utils/axios.js:
import axios from 'axios';
export const baseURL = 'https://example.com';
export default axios.create({ baseURL });
frontend/src/utils/constants.js:
const API_BASE_ORIGIN = 'wss://46.111.119.161';
export { API_BASE_ORIGIN };
...我在这里尝试了这些,但 none 有效:
const API_BASE_ORIGIN = 'https://example.com';
const API_BASE_ORIGIN = 'ws://46.111.119.161:5001';
const API_BASE_ORIGIN = 'ws://46.111.119.161';
const API_BASE_ORIGIN = 'wss://46.111.119.161';
const API_BASE_ORIGIN = 'wss://46.111.119.161:5001';
部分socketContext.js:
//* socket connection
useEffect(() => {
const newSocket = socketIo.connect(API_BASE_ORIGIN, {
transports: ['websocket'],
});
setSocket(newSocket);
if (!newSocket) return;
newSocket.on('connect', () => {
console.log(`Hurrah Socket ${newSocket.id} Connected`);
});
}, []);
NGINX default.conf 配置文件:
upstream api {
server main-be:5001;
}
upstream client {
server main-fe:3000;
}
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://$host$request_uri;
}
# main server block
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
# enable subfolder method reverse proxy confs
include /config/nginx/proxy-confs/*.subfolder.conf;
# all ssl related config moved to ssl.conf
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / {
proxy_pass http://client;
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;
}
location /api {
proxy_pass http://api;
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;
}
location /ws/ {
proxy_pass http://client;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
}
解决方案:
将
WDS_SOCKET_PORT=0
添加到 React 前端 .env 文件。 (所以它不会添加不必要的额外端口)将 nginx default.conf 配置文件编辑为这个(不是整个文件):
location /socket.io { proxy_pass http://api; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; }
setupProxy.js 文件:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://main-be:5001',
changeOrigin: true,
})
);
};
frontend/src/utils/axios.js:
import axios from 'axios';
export const baseURL = 'https://example.com';
export default axios.create({ baseURL });
frontend/src/utils/constants.js:
const API_BASE_ORIGIN = 'https://example.com';
export { API_BASE_ORIGIN };