gpt4 book ai didi

docker - 如果使用 docker 部署,为什么 MERN 应用程序无法与后端通信?

转载 作者:行者123 更新时间:2023-12-05 05:42:48 25 4
gpt4 key购买 nike

我使用 Docker 将 MERN 应用程序部署到 digital ocean 水滴。如果我在我的 PC 上本地运行 docker-compose.yml 文件,它运行良好。我有 2 个容器:1 个后端,1 个前端。如果我尝试在 Droplet 上进行组合,前端似乎没问题,但无法与后端通信。

enter image description here

我使用 http-proxy-middleware,我的 setupProxy.js 文件:

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://0.0.0.0:5001',
changeOrigin: true,
})
);
};

我试过 target: 'http://main-be:5001', 也是,因为 main-be 是我的后端容器的名称,但得到相同的错误。只是请求 URL 在 chrome 中是 http://main-be:5001/api/auth/login/devops/网络

enter image description here

...还有另一页: enter image description here

我的 docker-compose.yml 文件:

version: '3.4'

networks:
main:

services:
main-be:
image: main-be:latest
container_name: main-be
ports:
- '5001:5001'
networks:
main:
volumes:
- ./backend/config.env:/app/config.env
command: 'npm run prod'
main-fe:
image: main-fe:latest
container_name: main-fe
networks:
main:
volumes:
- ./frontend/.env:/app/.env
ports:
- '3000:3000'
command: 'npm start'

frontend 文件夹中的Dockerfile:

FROM node:12.2.0-alpine
COPY . .
RUN npm ci
CMD ["npm", "start"]

backend 文件夹中的Dockerfile:

FROM node:12-alpine3.14
WORKDIR /app
COPY . .
RUN npm ci --production
CMD ["npm", "run", "prod"]

backend/package.json 文件:

  "scripts": {
"start": "nodemon --watch --exec node --experimental-modules server.js",
"dev": "nodemon server.js",
"prod": "node server.js"
},

前端/.env 文件:

SKIP_PREFLIGHT_CHECK=true
HOST=0.0.0.0

backend/config.env 文件:

DE_ENV=development
PORT=5001

我的 deploy.sh 脚本构建图像,复制到 Droplet...

#build and save backend and frontend images
docker build -t main-be ./backend & docker build -t main-fe ./frontend
docker save -o ./main-be.tar main-be & docker save -o ./main-fe.tar main-fe

#deploy services
ssh root@46.111.119.161 "pwd && mkdir -p ~/apps/first && cd ~/apps/first && ls -al && echo 'im in' && rm main-be.tar && rm main-fe.tar &> /dev/null"

#::scp file
#scp ./frontend/.env root@46.111.119.161:~/apps/first/frontend

#upload main-be.tar and main-fe.tar to VM via ssh
scp ./main-be.tar ./main-fe.tar root@46.111.119.161:~/apps/thesis/

scp ./docker-compose.yml root@46.111.119.161:~/apps/first/
ssh root@46.111.119.161 "cd ~/apps/first && ls -1 *.tar | xargs --no-run-if-empty -L 1 docker load -i"

ssh root@46.111.119.161 "cd ~/apps/first && sudo docker-compose up"

前端/src/utils/axios.js:

import axios from 'axios';

export const baseURL = 'http://localhost:5001';

export default axios.create({ baseURL });

frontend/src/utils/constants.js:

const API_BASE_ORIGIN = `http://localhost:5001`;

export { API_BASE_ORIGIN };

我已经尝试了好几天,但看不出问题出在哪里,非常感谢任何帮助。

最佳答案

我不是 MERN 方面的专家(我们主要运行 Angular 和 .Net),但我必须警告您一件事。我们在一开始设置它时遇到了一个问题,它在容器中本地工作,但在我们的部署服务器上却不行,因为我们忘记了有关 Web 应用程序的基本知识。

应用程序在您的浏览器中运行,而如果您在其他地方部署应用程序堆栈,服务的 REST(API、数据库等)则不会。所以在你的应用程序中引用你的 IP/DNS/localhost 是行不通的,因为那里什么都没有。包含 WEB 应用程序的容器仅服务于您的浏览器(客户端)文件,然后 JS 和逻辑在您的浏览器中执行,而不是在容器中执行。

我怀疑这可能会影响您连接到后端的能力。

要解决这个问题,您有两个选择。

  • 创建一个 HTTP 代理作为附加服务,然后您的 FE 调用该代理(设置域和路由),例如 Nginx、Traefik 等,然后该代理可以使用服务名称引用您的后端,因为它确实与 API 存在于相同的环境中。
  • 直接从容器公开 HTTP 端口,然后您的 FE 可以调用 remoteServerIP:exposedPort,您将直接连接到容器的接口(interface)。 (注意:我不推荐这种方式用于实际使用,仅用于测试不使用任何代理的直接连接)

关于docker - 如果使用 docker 部署,为什么 MERN 应用程序无法与后端通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71952390/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com