尝试对 MERN 应用程序进行 dockerize 时出现代理错误

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

目前我正在开发一个 MERN 应用程序,我正处于开发的最后阶段,因为我想对我的应用程序进行 docker 化。我在本地使用 MongoDB,使用 MongoDBCompass。用户也只能在每台计算机本地使用它。现在我希望用户能够在其中长期存储数据,即使在停止 docker 并重新 docker 组合之后也是如此。但目前,当我尝试从前端从数据库获取数据时,出现此错误:

2024-05-01 10:04:44 arkheia-react-client  | Proxy error: Could not proxy request /simulation_runs from localhost:3000 to http://localhost:4000.
2024-05-01 10:04:44 arkheia-react-client  | See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).

这特别有趣,因为当我尝试访问后端时,网页在地址处工作正常:

http://localhost:4000/

我尝试了不同的方法,甚至安装了

cors
包,但没有成功。这是我的
docker-compose.yml
文件:

version: '3'

services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    image: arkheia-client
    container_name: arkheia-react-client
    command: npm start
    volumes:
      - ./frontend/:/usr/app
      - /usr/app/node_modules
    depends_on:
      - backend
    ports:
      - "3000:3000"
    networks:
      - app-network

  backend:
    build:
      context: ./server
      dockerfile: Dockerfile
    image: arkheia-server
    container_name: arkheia-node-server
    command: npm start
    volumes:
      - ./server/:/usr/src/app
      - /usr/src/app/node_modules
    ports:
      - "4000:4000"
    depends_on:
      - database
    env_file: ./server/.env
    networks:
      - app-network

  database:
    image: mongo
    volumes:
      - data-volume:/data/db
    ports:
      - "27017:27017"
    networks:
    - app-network
    container_name: arkheia-database

networks:
  app-network:
    driver: bridge

volumes:
    data-volume:
    node_modules:
    web-root:
      driver: local

和我的 server.js:

require('dotenv').config() // Require as here are defined MongoDB credentials

const express  = require('express');
const mongoose = require('mongoose');
const multer = require('multer');
const path = require('path');
const { GridFSBucket } = require('mongodb');

const aboutRoutes = require('./routes/about')
const documentationRoutes = require('./routes/documentation')
const simulationRunsRoutes = require('./routes/simulation_runs')
const stimuliRoutes = require('./routes/stimuli')
const expProtocolRoutes = require('./routes/exp_protocol')
const recordRoutes = require('./routes/records')
const resultRoutes = require('./routes/results')
const parameterSearchRoutes = require('./routes/parameter_searches')

// Define multer storage for middle end
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './uploads/');
    },
    filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname)); 
    }
});

const upload = multer({ storage: storage });

const app = express();

// The express middle end
app.use(express.json({ limit: '50mb' }))


app.use((req, res, next) => {
    console.log(req.path, req.method)
    next();
})

// Connection to the database
mongoose.connect(process.env.MONGODB_URI)
    .then(() => {
        const conn = mongoose.connection;
        gfs = new GridFSBucket(conn.db, {
            bucketName: 'uploads' // The GridFS bucket name
        });

        // Routes
        app.use('/about', aboutRoutes)

        app.use('/documentation', documentationRoutes)

        app.use('/simulation_runs', simulationRunsRoutes)

        app.use('/stimuli', upload.single('movie', (err, req, res, next) => {
            if (err) {
                console.error('Multer Error:', err);
                res.status(400).json({ error: 'Error during file upload' });
            } else {
                next();
            }
        }), stimuliRoutes);

        app.use('/exp_protocols', expProtocolRoutes);

        app.use('/records', recordRoutes);

        app.use('/results', upload.single('figure', (err, req, res, next) => {
            if (err) {
                console.error('Multer Error:', err);
                res.status(400).json({ error: 'Error during file upload' });
            } else {
                next();
            }
        }), resultRoutes); 

        app.use('/parameter_searches', parameterSearchRoutes);

        app.listen(process.env.PORT, () => {
            console.log("Server running in port 4000");
        })
        console.log("Successfully connected to mongodb");
    })
    .catch((error) => {
        console.log(error);
    })


module.exports = app;

前端的

package.json
文件如下所示:

{
  "proxy": "http://localhost:4000",
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "bootstrap": "^5.3.2",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-icons": "^4.11.0",
    "react-json-tree": "^0.18.0",
    "react-markdown": "^9.0.0",
    "react-router-dom": "^6.16.0",
    "react-scripts": "5.0.1",
    "reactstrap": "^9.2.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

现在我在这里读到有关

proxy
字段的信息,这可能会导致问题,但我真的不知道它会如何影响 docker 图像。我真的不想仅仅为了 Docker 化这个应用程序而使用 nginx 或任何其他库。

我省略了前端和后端的 Dockerfile:

前端:

# Dockerfile for React client

# Build react client
FROM node:alpine


# Working directory be app
WORKDIR /usr/src/app

COPY package*.json ./

###  Installing dependencies

RUN npm install --silent

# copy local files to app folder
COPY . .

EXPOSE 3000

CMD ["npm","start"]

后端:

#  Dockerfile for Node Express Backend

FROM node:alpine

# Create App Directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install Dependencies
COPY package*.json ./

RUN npm install --silent

# Copy app source code
COPY . .

# Exports
EXPOSE 4000

CMD ["npm","start"]

有什么想法吗?是什么原因导致了这个问题?我没有看到这个问题的解决方案,所以我在这里寻求帮助。

node.js mongodb docker express
1个回答
0
投票

答案是将应用程序前端部分的 package.json 文件内的代理字段更改为:

"proxy": "http://arkheia-node-server:4000"

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