第一步,我尝试使用两个容器构建一个堆栈,一个使用应用程序构建,一个使用MS SQL服务器构建。不使用堆栈,并且在本地使用SQL Server和应用程序的容器都可以正常工作,但是我无法设法找出使容器化的应用程序连接到数据库的正确方法。
我的堆栈文件如下:
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:
Db映像基于microsoft / mssql-server-linux:2017-latest,当应用程序不在容器中并且使用“ localhost”作为主机名时可以正常工作。
在节点应用中,mssql配置如下:
const config = {
user: '<username>',
password: '<password>',
server: 'db',
database: 'library',
options: {
encrypt: false // Use this if you're on Windows Azure
}
};
还有我从节点应用程序容器收到的消息:
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或通过代码连接数据库的方法。
答案 0 :(得分:0)
最终使其正常运行。
有关更简单有效的堆栈文件,请参见OP。 此外,我在我的应用程序代码中添加了重试策略,以使MS SQL Server有时间在容器中正确启动。
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文档本身建议通过代码或添加延迟脚本来管理此问题。