目前我正在开发一个 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"]
有什么想法吗?是什么原因导致了这个问题?我没有看到这个问题的解决方案,所以我在这里寻求帮助。
答案是将应用程序前端部分的 package.json 文件内的代理字段更改为:
"proxy": "http://arkheia-node-server:4000"