作为第一步,我尝试构建一个包含两个容器的堆栈,一个包含应用程序,一个包含 MS SQL 服务器。不使用堆栈,并且带有 SQL 服务器和应用程序的容器在本地工作正常,但我无法找出使容器化应用程序连接到数据库的正确方法。
我的堆栈文件如下:
version: "3.4"
services:
db:
image: orizon/training-library-sql
ports:
- 1443:1443
networks:
- backend
app:
image: orizon/training-library
ports:
- 4000:4000
networks:
- backend
depends_on:
- db
links:
- db:db
deploy:
replicas: 1
networks:
backend:
数据库镜像基于 microsoft/mssql-server-linux:2017-latest,当应用程序不在容器中并使用“localhost”作为主机名时,该镜像可以正常工作。
在 Node 应用程序中,mssql 配置如下:
const config = {
user: '<username>',
password: '<password>',
server: 'db',
database: 'library',
options: {
encrypt: false // Use this if you're on Windows Azure
}
};
以及我从 Node 应用程序容器收到的消息:
2018-09-07T10:11:57.404Z app ConnectionError: Failed to connect to db:1433 - getaddrinfo ENOTFOUND db
<小时/>
编辑
简化了我的堆栈文件,连接现在可以正常工作了。
links
似乎已弃用并替换为 depends_on
version: "3.4"
services:
db:
image: orizon/training-library-sql
ports:
- 1443:1443
app:
image: orizon/training-library
ports:
- 4000:4000
depends_on:
- db
deploy:
replicas: 1
现在错误消息发生了变化,让我认为这更像是一种延迟问题。数据库容器似乎需要更多时间来准备才能弹出应用程序容器。 我想我现在正在寻找通过 docker 或代码延迟连接到数据库的方法。
最佳答案
终于可以正常使用了。
请参阅 OP 以获取更简单且有效的堆栈文件。 此外,我在应用代码中添加了重试策略,以便 MS SQL 服务器有时间在容器中正确启动。
function connectWithRetry() {
return sql.connect(config, (err) => {
if (err) {
debug(`Connection to DB failed, retry in 5s (${chalk.gray(err.message)})`);
sql.close();
setTimeout(connectWithRetry, 5000);
} else {
debug('Connection to DB is now ready...');
}
});
}
connectWithRetry();
Docker 文档显示了一个应该回答此问题的参数 (sequential_deployment: true
),但 docker stack
不允许使用它。 Docker 文档本身建议通过代码或添加延迟脚本来管理此问题。
关于node.js - docker stack与mssql和node,如何正确连接到数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52220961/