Reputation: 1672
I'm working with a docker service using docker-compose, and I have a service that depends on anther.
I've used the depends_on
key, but the service with the dependency launches prior to the depending service being completely up.
version: '3'
services:
KeyManager:
image: cjrutherford/keymanager
deploy:
replicas: 1
ports:
- '3220:3220'
networks:
- privnet
YellowDiamond:
image: cjrutherford/server
depends_on:
- KeyManager
deploy:
replicas: 1
ports:
- '3000:3000'
networks:
- privnet
- web
networks:
privnet:
internal: true
web:
Both of these are node applications, and the keymanager is required to be running to accept requests before the server launches. Can I add a timeout? or send a trigger in the app? it's just launching way too early to get the key from the manager.
Upvotes: 29
Views: 51338
Reputation: 3159
I use wait-for-it.sh on nodejs on centos 8 and got the following error.
myimage-data-api | /usr/src/app/wait-for-it.sh:2
myimage-data-api | # Use this script to test if a given TCP host/port
are available
myimage-data-api | ^
myimage-data-api |
myimage-data-api | SyntaxError: Invalid or unexpected token
myimage-data-api | at Object.compileFunction (node:vm:352:18)
myimage-data-api | at wrapSafe
(node:internal/modules/cjs/loader:1026:15)
myimage-data-api | at Module._compile
(node:internal/modules/cjs/loader:1061:27)
myimage-data-api | at Object.Module._extensions..js
(node:internal/modules/cjs/loader:1149:10)
myimage-data-api | at Module.load
(node:internal/modules/cjs/loader:975:32)
myimage-data-api | at Function.Module._load
(node:internal/modules/cjs/loader:822:12)
myimage-data-api | at Function.executeUserEntryPoint [as runMain]
(node:internal/modules/run_main:81:12)
myimage-data-api | at node:internal/main/run_main_module:17:47
myimage-data-api |
myimage-data-api | Node.js v17.3.0
Upvotes: 0
Reputation: 14806
You are probably looking for docker compose healthcheck
and the Long Syntax form of depends_on
.
The behavior for this feature has changed between docker-copmose versions, so here is the updated way to do so (this docker-compose file works as is):
services:
db:
image: postgres
environment:
- POSTGRES_USER=king
- POSTGRES_DB=kong
- POSTGRES_HOST_AUTH_METHOD=trust
healthcheck:
test: pg_isready -U postgres
web:
image: alpine
depends_on:
db:
condition: service_healthy
Then run docker-compose run web
, and it will wait for the database before starting.
There is also a more detailed form of the healthcheck
directive:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
Notes:
version
directive (reference)Upvotes: 24
Reputation: 216
I've often found using a wait-for-it bash script much more effective than the built in health check to docker-compose.
This runs a TCP health check against a given port and waits until this is complete before starting to run a process.
Sample code:
version: "2"
services:
web:
build: .
ports:
- "80:8000"
depends_on:
- "db"
command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
db:
image: postgres
Here's some docs:
Upvotes: 19