Docker swarm secret 在 node.js api (mongoDB) 中无法正常工作
Docker swarm secret not working correctly in node.js api (mongoDB)
我正在尝试将我的 mongo_username 和 mongo_password 放入 swarm secret 中,但由于某种原因它们被转换了?我在容器日志中收到此错误
/usr/src/app/node_modules/saslprep/index.js:99
throw new Error(
^
Error: Prohibited character, see https://tools.ietf.org/html/rfc4013#section-2.3
at saslprep (/usr/src/app/node_modules/saslprep/index.js:99:11)
at continueScramConversation (/usr/src/app/node_modules/mongodb/lib/core/auth/scram.js:126:36)
at /usr/src/app/node_modules/mongodb/lib/core/auth/scram.js:111:5
at MessageStream.messageHandler (/usr/src/app/node_modules/mongodb/lib/cmap/connection.js:277:5)
at MessageStream.emit (events.js:315:20)
at processIncomingData (/usr/src/app/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
at MessageStream._write (/usr/src/app/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
at writeOrBuffer (_stream_writable.js:353:12)
at MessageStream.Writable.write (_stream_writable.js:303:12)
at Socket.ondata (_stream_readable.js:713:22)
at Socket.emit (events.js:315:20)
at addChunk (_stream_readable.js:302:12)
at readableAddChunk (_stream_readable.js:278:9)
at Socket.Readable.push (_stream_readable.js:217:10)
at TCP.onStreamRead (internal/stream_base_commons.js:186:23)
我是这样添加的secret
echo admin | docker secret create mongo_username -
echo totallySecurePassword23456789 | docker secret create mongo_password -
当我像这样在我的数据库连接函数中记录这两个秘密时:
const mongoose = require("mongoose"); // For connection to DB
const {
MONGO_USERNAME,
MONGO_PASSWORD,
MONGO_HOSTNAME,
MONGO_PORT,
MONGO_DATABASE_NAME,
} = process.env;
console.log(MONGO_USERNAME);
console.log(MONGO_PASSWORD);
console.log(MONGO_HOSTNAME);
console.log(MONGO_PORT);
console.log(MONGO_DATABASE_NAME);
const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DATABASE_NAME}?retryWrites=true$w=majority`;
console.log(url);
const connectDB = async () => {
const conn = await mongoose.connect(url, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
});
console.log(`MongoDB Connected: ${conn.connection.host}`.cyan.underline.bold);
};
module.exports = connectDB;
它们正确显示为:
admin
totallySecurePassword23456789
host.docker.internal
27020
mainDB
然而 url 应该看起来像 mongodb://admin:totallySecurePassword23456789@host.docker.internal:27020/mainDB?retryWrites=true$w=majority
显示为 @host.docker.internal:27020/mainDB?retryWrites=true$w=majority
这当然会使连接失败
主机名、端口和 database_name 工作正常,因为它们被定义为普通环境变量
非常感谢任何帮助,如果需要更多信息,请告诉我!
编辑 1:
这是我用来 运行 docker 堆栈的 docker-compose 文件:
version: "3.8"
services:
main:
image: main:5.0.0
environment:
- MONGO_USERNAME_FILE=/run/secrets/mongo_username
- MONGO_PASSWORD_FILE=/run/secrets/mongo_password
- MONGO_HOSTNAME=host.docker.internal
- MONGO_PORT=27020
- MONGO_DATABASE_NAME=mainDB
secrets:
- mongo_username
- mongo_password
networks:
- main-net
ports:
- "80:3001"
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 10s
window: 60s
networks:
main-net:
driver: overlay
secrets:
mongo_username:
external: true
mongo_password:
external: true
编辑 2:
修复了撰写文件缺少用户名和密码后面的 _FILE
经过大量调查后我发现我遇到了这个问题https://github.com/aspnet/Configuration/issues/701, with no good fix found i settled on editing the entrypoint i was using (https://github.com/BretFisher/node-docker-good-defaults/blob/main/docker-entrypoint.sh) 所以它在使用
将其设置为环境变量之前删除了行尾内容
export "$var"="${val//[$'\t\r\n ']}"
我假设你使用 gnu bash。如果您使用不带 -n 选项的 echo shell 内置函数,它会自动向提供的字符串添加新行。
试试这些:
echo -n admin | docker secret create mongo_username -
echo -n totallySecurePassword23456789 | docker secret create mongo_password -
如果你想检查你的秘密值是否包括新行,在你的docker cli所在的机器上执行以下命令:
docker container exec <your_container_name or id> cat -e /run/secrets/<your_secret_name>
如果此命令 returns 您的值后跟 $ 符号,那么我们可以得出结论,在您创建机密时附加了换行符。
注意:我假设您的容器是 linux 容器。此外,请确保您的容器处于 运行 状态,并且其 PATH 环境变量必须包含 cat 二进制文件所在的目录路径。
我正在尝试将我的 mongo_username 和 mongo_password 放入 swarm secret 中,但由于某种原因它们被转换了?我在容器日志中收到此错误
/usr/src/app/node_modules/saslprep/index.js:99
throw new Error(
^
Error: Prohibited character, see https://tools.ietf.org/html/rfc4013#section-2.3
at saslprep (/usr/src/app/node_modules/saslprep/index.js:99:11)
at continueScramConversation (/usr/src/app/node_modules/mongodb/lib/core/auth/scram.js:126:36)
at /usr/src/app/node_modules/mongodb/lib/core/auth/scram.js:111:5
at MessageStream.messageHandler (/usr/src/app/node_modules/mongodb/lib/cmap/connection.js:277:5)
at MessageStream.emit (events.js:315:20)
at processIncomingData (/usr/src/app/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
at MessageStream._write (/usr/src/app/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
at writeOrBuffer (_stream_writable.js:353:12)
at MessageStream.Writable.write (_stream_writable.js:303:12)
at Socket.ondata (_stream_readable.js:713:22)
at Socket.emit (events.js:315:20)
at addChunk (_stream_readable.js:302:12)
at readableAddChunk (_stream_readable.js:278:9)
at Socket.Readable.push (_stream_readable.js:217:10)
at TCP.onStreamRead (internal/stream_base_commons.js:186:23)
我是这样添加的secret
echo admin | docker secret create mongo_username -
echo totallySecurePassword23456789 | docker secret create mongo_password -
当我像这样在我的数据库连接函数中记录这两个秘密时:
const mongoose = require("mongoose"); // For connection to DB
const {
MONGO_USERNAME,
MONGO_PASSWORD,
MONGO_HOSTNAME,
MONGO_PORT,
MONGO_DATABASE_NAME,
} = process.env;
console.log(MONGO_USERNAME);
console.log(MONGO_PASSWORD);
console.log(MONGO_HOSTNAME);
console.log(MONGO_PORT);
console.log(MONGO_DATABASE_NAME);
const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DATABASE_NAME}?retryWrites=true$w=majority`;
console.log(url);
const connectDB = async () => {
const conn = await mongoose.connect(url, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
});
console.log(`MongoDB Connected: ${conn.connection.host}`.cyan.underline.bold);
};
module.exports = connectDB;
它们正确显示为:
admin
totallySecurePassword23456789
host.docker.internal
27020
mainDB
然而 url 应该看起来像 mongodb://admin:totallySecurePassword23456789@host.docker.internal:27020/mainDB?retryWrites=true$w=majority
显示为 @host.docker.internal:27020/mainDB?retryWrites=true$w=majority
这当然会使连接失败
主机名、端口和 database_name 工作正常,因为它们被定义为普通环境变量
非常感谢任何帮助,如果需要更多信息,请告诉我!
编辑 1: 这是我用来 运行 docker 堆栈的 docker-compose 文件:
version: "3.8"
services:
main:
image: main:5.0.0
environment:
- MONGO_USERNAME_FILE=/run/secrets/mongo_username
- MONGO_PASSWORD_FILE=/run/secrets/mongo_password
- MONGO_HOSTNAME=host.docker.internal
- MONGO_PORT=27020
- MONGO_DATABASE_NAME=mainDB
secrets:
- mongo_username
- mongo_password
networks:
- main-net
ports:
- "80:3001"
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 10s
window: 60s
networks:
main-net:
driver: overlay
secrets:
mongo_username:
external: true
mongo_password:
external: true
编辑 2: 修复了撰写文件缺少用户名和密码后面的 _FILE
经过大量调查后我发现我遇到了这个问题https://github.com/aspnet/Configuration/issues/701, with no good fix found i settled on editing the entrypoint i was using (https://github.com/BretFisher/node-docker-good-defaults/blob/main/docker-entrypoint.sh) 所以它在使用
将其设置为环境变量之前删除了行尾内容
export "$var"="${val//[$'\t\r\n ']}"
我假设你使用 gnu bash。如果您使用不带 -n 选项的 echo shell 内置函数,它会自动向提供的字符串添加新行。
试试这些:
echo -n admin | docker secret create mongo_username -
echo -n totallySecurePassword23456789 | docker secret create mongo_password -
如果你想检查你的秘密值是否包括新行,在你的docker cli所在的机器上执行以下命令:
docker container exec <your_container_name or id> cat -e /run/secrets/<your_secret_name>
如果此命令 returns 您的值后跟 $ 符号,那么我们可以得出结论,在您创建机密时附加了换行符。
注意:我假设您的容器是 linux 容器。此外,请确保您的容器处于 运行 状态,并且其 PATH 环境变量必须包含 cat 二进制文件所在的目录路径。