我正在用 Express 和 MongoDB 做一個 REST API。一切都在本地完美運行。我想使用 Docker Compose 對資料庫和后端進行 dockerize。
Mongo Docker 運行良好,但后端無法連接到它。它不斷向我拋出這個錯誤:
/backend/node_modules/mongoose/lib/connection.js:797
const serverSelectionError = new ServerSelectionError();
^
MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
at NativeConnection.Connection.openUri (/backend/node_modules/mongoose/lib/connection.js:797:32)
at /backend/node_modules/mongoose/lib/index.js:341:10
at /backend/node_modules/mongoose/lib/helpers/promiseOrCallback.js:32:5
at new Promise (<anonymous>)
at promiseOrCallback (/backend/node_modules/mongoose/lib/helpers/promiseOrCallback.js:31:10)
at Mongoose._promiseOrCallback (/backend/node_modules/mongoose/lib/index.js:1167:10)
at Mongoose.connect (/backend/node_modules/mongoose/lib/index.js:340:20)
at Object.<anonymous> (/backend/index.js:11:3)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10) {
reason: TopologyDescription {
type: 'Unknown',
servers: Map(1) {
'localhost:27017' => ServerDescription {
_hostAddress: HostAddress { isIPv6: false, host: 'localhost', port: 27017 },
address: 'localhost:27017',
type: 'Unknown',
hosts: [],
passives: [],
arbiters: [],
tags: {},
minWireVersion: 0,
maxWireVersion: 0,
roundTripTime: -1,
lastUpdateTime: 14312460,
lastWriteDate: 0,
error: MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017
at connectionFailureError (/backend/node_modules/mongodb/lib/cmap/connect.js:293:20)
at Socket.<anonymous> (/backend/node_modules/mongodb/lib/cmap/connect.js:267:22)
at Object.onceWrapper (node:events:510:26)
at Socket.emit (node:events:390:28)
at emitErrorNT (node:internal/streams/destroy:164:8)
at emitErrorCloseNT (node:internal/streams/destroy:129:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
}
},
stale: false,
compatible: true,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
logicalSessionTimeoutMinutes: undefined
}
}
我在網上讀到問題可能是我不應該連接到 localhost 而是連接到 MongoDB 容器。
我附上檔案:
碼頭工人-compose.yml
version: '3.8'
services:
data:
container_name: data
image: mongo
ports:
- 27017:27017
volumes:
- ./data/db:/data/db
backend:
container_name: backend
depends_on:
- data
build: ./backend
ports:
- 5000:5000
environment:
- DB_HOST=data
- DB_NAME=${DB_NAME?:}
- DB_PORT=${DB_PORT?:}
/后端/Dockerfile
# pull official base image
FROM node:latest
# set working directory
WORKDIR /backend
EXPOSE 5000
ENV PORT=5000
ENV HOST=0.0.0.0
# install backend dependencies
COPY package*.json ./
RUN npm ci --only-production
# add backend
COPY . .
# start backend
CMD npm start
/后端/index.js
const express = require("express")
const mongoose = require("mongoose")
const property = require("./routes/property-router")
const properties = require("./routes/properties-router")
const statistics = require("./routes/statistics-router")
const bodyParser = require("body-parser")
const dbConfig = require("./config/db.config")
require("dotenv").config();
var cors = require("cors")
// Connect to MongoDB database
mongoose
.connect(dbConfig.url, { useNewUrlParser: true })
.then(() => {
const app = express()
app.use(cors())
app.use(bodyParser.text({ type: '*/*'}))
app.use("/api", statistics)
app.use("/api", properties)
app.use("/api", property)
const PORT = dbConfig.port || 5000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
})
/backend/config/db.config.js
require('dotenv').config();
const {
DB_HOST,
DB_PORT,
DB_NAME,
PORT,
} = process.env;
module.exports = {
url: `mongodb://${DB_HOST}:${DB_PORT}/${DB_NAME}`,
port: PORT
};
/后端/.env
PORT=5000
HOST=localhost
DB_HOST=localhost
DB_NAME=propertyDB
DB_PORT=27017
在本地運行后端我可以毫無問題地連接到 MongoDB Docker。通過只保留 Docker Compose 檔案中的資料并運行節點 index.js。
我究竟做錯了什么?
編輯
我什至將 URL 從 index.js 更改為隨機 URL,但仍然出現相同的錯誤并嘗試連接到 127.0.0.1:27017。
.connect("randomurl.com", { useNewUrlParser: true })
uj5u.com熱心網友回復:
Docker 容器的行為類似于網路中的節點。除非您告訴它不要這樣做,否則 Docker Compose 會創建一個虛擬網路,并在該網路內分配與檔案中的服務名稱相對應的 DNS 名稱docker-compose.yml。中的值會.env覆寫 中的環境變數docker-compose.yml。
您可以洗掉(即不復制)檔案并通過添加到.env使用環境變數設定值。.env.dockerignore
或者,您可以更改
DB_HOST=localhost
到
DB_HOST=data
在.env. 該.env檔案應包含
PORT=5000
HOST=localhost
DB_HOST=data
DB_NAME=propertyDB
DB_PORT=27017
uj5u.com熱心網友回復:
問題是,當您運行 docker compose 時,會創建并存盤一個新影像。所以每次你運行同一個容器時,都會執行同一個鏡像。您需要做的是:
第一步,您應該首先關閉所有正在運行的 docker-compose 配置:
$ docker-compose down
您可以使用以下命令來驗證是否沒有任何東西在運行:
$ docker ps --all
要洗掉本地構建的影像,首先列出本地快取的所有影像,然后洗掉本地構建的任何內容:
$ docker images
然后洗掉給您帶來問題的影像。
$ docker rmi <image_name>
這解決了這個問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/414717.html
標籤:
