-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
Is your feature request related to a problem? Please describe.
I am working on a project that heavy use of depends_on filed with conditions when creating containers. This allows us to run databases, migrations, and applications reliably.
My situation can be compared to the below docker-compose.yaml file
services:
db:
image: debian:buster-slim
command:
- bash
- -c
- |
echo "Start"
for x in $$(seq 1 5); do sleep 1; echo "sleep $${x}/5"; done;
touch /migartion-done;
echo "OK";
for x in $$(seq 1 60); do sleep 10; echo "sleep $$((x * 10))/600";done;
healthcheck:
test: ["CMD-SHELL", "test -f /migartion-done"]
interval: "1s"
retries: 30
app-init:
image: debian:buster-slim
command:
- bash
- -c
- |
echo "OK";
depends_on:
db:
condition: service_healthy
app:
image: debian:buster-slim
command:
- bash
- -c
- |
echo "Start"
for x in $$(seq 1 5); do sleep 1; echo "sleep $${x}/5"; done;
touch /webserver-started"
for x in $$(seq 1 60); do sleep 10; echo "sleep $$((x * 10))/600";done;
healthcheck:
test: [ "CMD-SHELL", "test -f /webserver-started" ]
interval: "1s"
retries: 30
depends_on:
app-init:
condition: service_completed_successfully
db:
condition: service_healthyWhere
dbis a service that runs continuously but takes a while to start. Other containers should not start until this service is started and is healthy.condition: service_healthyapp-initis a one-run container. Other containers should not start until this service is started and finish.condition: service_completed_successfullyappis a service that runs continuously but takes a while to start.
Currently, after executing the docker-compose up command, all containers are started/completed, but docker-compose only ensures that the db and app-init containers are healthy/completed. The app container is still in an unhealthy condition.
Describe the solution you'd like
It would be fantastic if docker-compose also took into account the state of the last container (app) and waited for it to report the correct healthy status. This may be protected by an additional flag, e.g. --wait-for-healthy-status.
Describe alternatives you've considered
For now, I have implemented the health check logic in my scripts, but this is code duplication.
Alternatively, we can also add the ability to list containers by health status to docker ps --services . The docker-compose command has filters, but they are very limited. It supports only 4 states: running, stopped, paused, restarting.
Lines 1634 to 1667 in 73f8cf9
| def has_container_with_state(containers, state): | |
| states = { | |
| 'running': lambda c: c.is_running, | |
| 'stopped': lambda c: not c.is_running, | |
| 'paused': lambda c: c.is_paused, | |
| 'restarting': lambda c: c.is_restarting, | |
| } | |
| for container in containers: | |
| if state not in states: | |
| raise UserError("Invalid state: %s" % state) | |
| if states[state](container): | |
| return True | |
| def filter_services(filt, services, project): | |
| def should_include(service): | |
| for f in filt: | |
| if f == 'status': | |
| state = filt[f] | |
| containers = project.containers([service.name], stopped=True) | |
| if not has_container_with_state(containers, state): | |
| return False | |
| elif f == 'source': | |
| source = filt[f] | |
| if source == 'image' or source == 'build': | |
| if source not in service.options: | |
| return False | |
| else: | |
| raise UserError("Invalid value for source filter: %s" % source) | |
| else: | |
| raise UserError("Invalid filter: %s" % f) | |
| return True | |
| return filter(should_include, services) |
When we add support for the health status filter, it will be much easier for me to write a script waiting for all containers.
while [[ "$(docker-compose ps --services --filter state=unhealthy)" == "" ]]; do sleep 1; echo sleep 1; done;
@trajano proposed to add a separate command that will allow us to check the condition of the containers. #6408
Additional context
Add any other context or screenshots about the feature request here.
CC: @shin- , @ulyssessouza