这就是我的意思。如何编写docker-compose.yaml文件,以便在“构建”一项服务时首先运行另一项服务?
我会尝试更加具体。我正在尝试使用数据库库JOOQ构建Java应用程序,该数据库要在构建时连接到数据库,以便生成与数据库表相对应的Java类。我希望将Dockerfile和docker-compose.yaml文件进行某种组合,以便大致按以下顺序进行以下操作。
这是我正在使用的docker-compose.yaml文件
version: '3.7'
services:
postgres:
image: postgres:10.5-alpine
restart: always
ports:
- "6432:5432"
environment:
POSTGRES_DB: flashtools
POSTGRES_USER: flashtools
POSTGRES_PASSWORD: flashtools
volumes:
- ./src/main/scripts/01_init.sql:/docker-entrypoint-
initdb.d/01_init.sql
web:
build: .
network_mode: host
depends_on:
- postgres
ports:
- "8080:8080"
我将用更多细节对此加以充实,但希望我要问的很简单。
答案 0 :(得分:0)
我遇到了同样的问题,并且以一种骇人听闻的方式解决了...
在我的情况下,Web服务是Haskell,它使用result
命令构建,然后使用stack build
执行。还有stack exec APP_NAME
之类的缩写。
还有一个选项可以仅使用stack build --exec APP_NAME
构建依赖项,因此Docker构建会缓存它们。
所以我这样更改了Dockerfile:
stack build --only-dependencies
因此最终版本仅在服务启动时运行。
我对Java的了解还不够,但是我想那里也必须有类似的选择。
还需要对depends_on部分进行一些修改: https://docs.docker.com/compose/startup-order/
答案 1 :(得分:0)
就我而言,Web 服务入口点是一个类似于 node server.js
的命令。
如果在调用时数据库已经可用,它会正常工作,但使用 docker-compose 时则不是这种情况。
一种解决方法是在您的 server.js
中编写代码,以便它重试直到数据库准备就绪。
在我的server.js
中:
connectDB()
.then(db => {
/* Use db here...*/
app.listen(3000);
});
async function connectDB() {
var retry = 5;
while (retry-- > 0 && !(dbReady()) {
await sleep(1000);
}
return useDB();
}
function dbReady() {
/* returns true iff DB available */
}
async function useDB() {
/* returns DB instance */
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}