我正在使用 docker compose 来拉起一个 MongoDB 容器和一个简单的 Node CRUD 应用程序,真的没什么花哨的。容器出现并且到目前为止似乎可以工作,但是当我尝试启用身份验证并使用 Compass 登录时,它总是显示“身份验证失败”,无论我使用什么用户或连接设置。检查 Mongo 容器内的日志,我可以看到用户的创建显然失败了,但我不知道为什么。请注意,我在下面的日志部分中发布的相同错误消息也以相同的方式向技术用户显示。
编辑:只是为了澄清一下,我将其部署在本地网络内我自己的开发服务器上,并且整个内容并不打算随时推送到某个公共服务器。仅供个人使用,您可以说;-)
这是我的 docker 撰写文件:
services:
mongodb:
image: mongo:latest
restart: unless-stopped
ports:
- "1335:27017"
volumes:
- database:/database
- ./config/UserInit.js:/docker-entrypoint-initdb.d/UserInit.js:ro
environment:
- "MONGO_INITDB_ROOT_USERNAME=${MONGO_USER}"
- "MONGO_INITDB_ROOT_PASSWORD=${MONGO_PW}"
- "MONGO_INITDB_DATABASE=banking"
stdin_open: true
tty: true
bankingbackend:
depends_on:
- mongodb
build: .
restart: unless-stopped
stdin_open: true
tty: true
ports:
- "1336:1336"
volumes:
database:
Dockerfile:
FROM node:latest
WORKDIR "/bankingBackend"
COPY . .
RUN npm install
CMD ["npm", "start"]
UserInit.js 应该创建另一个(技术)用户:
db.createUser(
{
user: process.env.MONGO_TEC_USER,
pwd: process.env.MONGO_TEC_USER_PASS,
roles: [
{
role: "readWrite",
db: "banking"
}
]
}
);
use("banking");
db.createCollection("accounts");
db.createCollection("transactions");
Jenkinsfile 触发构建并提供凭据作为环境变量:
pipeline {
agent any
stages {
stage('checkout') {
steps {
checkout scm
}
}
stage('docker-compose-up') {
steps {
withCredentials([
usernamePassword(credentialsId: 'Mongo tec user', passwordVariable: 'MONGO_PW', usernameVariable: 'MONGO_USER'),
usernamePassword(credentialsId: 'Mongo tec user', passwordVariable: 'MONGO_TEC_USER_PASS', usernameVariable: 'MONGO_TEC_USER')]) {
sh 'MONGO_USER=MONGO_USER MONGO_PW=MONGO_PW MONGO_TEC_USER_PASS=MONGO_TEC_USER_PASS MONGO_TEC_USER=MONGO_TEC_USER docker compose up -d --build --force-recreate'
}
}
}
}
}
日志:
"c":"ACCESS", "id":5286307, "ctx":"conn2","msg":"Failed to authenticate","attr":{"client":"192.166.124.101:53804","isSpeculative":false,"isClusterMember":false,"mechanism":"SCRAM-SHA-1","user":"adminUser","db":"admin","error":"UserNotFound: Could not find user \"adminUser\" for db \"admin\"","result":11,"metrics":{"conversation_duration":{"micros":451,"summary":{"0":{"step":1,"step_total":2,"duration_micros":421
当您使用这样的环境变量运行 docker-compose 时:
MONGO_USER=MONGO_USER MONGO_PW=MONGO_PW MONGO_TEC_USER_PASS=MONGO_TEC_USER_PASS MONGO_TEC_USER=MONGO_TEC_USER docker compose up -d --build --force-recreate 环境变量不会传递给 docker-compose 进程,而是传递给运行命令的 shell。
要将环境变量传递给 docker-compose 进程,可以使用 -e 标志,后跟变量名称和值,如下所示:
docker compose -e MONGO_USER=MONGO_USER -e MONGO_PW=MONGO_PW -e MONGO_TEC_USER_PASS=MONGO_TEC_USER_PASS -e MONGO_TEC_USER=MONGO_TEC_USER up -d --build --force-recreate 但是,如果您有很多环境变量,这可能会变得很麻烦。
更好的方法是在 docker-compose.yml 文件中定义环境变量,如下所示:
服务: 蒙戈数据库: ... 环境: - MONGO_INITDB_ROOT_USERNAME=${MONGO_USER} - MONGO_INITDB_ROOT_PASSWORD=${MONGO_PW} - MONGO_INITDB_DATABASE=银行业务 - MONGO_TEC_USER=${MONGO_TEC_USER} - MONGO_TEC_USER_PASS=${MONGO_TEC_USER_PASS} ...
然后,在你的 Jenkinsfile 中,你可以像这样传递环境变量:
withCredentials([ usernamePassword(credentialsId:'Mongo tec用户',passwordVariable:'MONGO_PW',usernameVariable:'MONGO_USER'), usernamePassword(credentialsId:'Mongo tec 用户',passwordVariable:'MONGO_TEC_USER_PASS',usernameVariable:'MONGO_TEC_USER')]){ sh 'docker compose -f docker-compose.yml up -d --build --force-recreate' } 这样,环境变量将被传递到 docker-compose 进程,并将可供您的容器使用。