Skip to content

Commit 6371103

Browse files
feat(docker-compose): allow people to disable the default wait behavior (#922)
Closes #877 by allowing people to optionally disable the `--wait` flag usually passed in Feel free to push any changes here or fixes / issues you have with it, would love a new release as soon as this is merged as well if it all possible
1 parent c3a8cb1 commit 6371103

4 files changed

Lines changed: 46 additions & 6 deletions

File tree

testcontainers/src/compose/client.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub(super) struct UpCommand {
2828
pub(super) env_vars: std::collections::HashMap<String, String>,
2929
pub(super) build: bool,
3030
pub(super) pull: bool,
31+
pub(super) wait: bool,
3132
}
3233

3334
pub(super) struct DownCommand {

testcontainers/src/compose/client/containerised.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ impl ComposeInterface for ContainerisedComposeCli {
7373
cmd_parts.push("always".to_string());
7474
}
7575

76-
cmd_parts.push("--wait".to_string());
77-
cmd_parts.push("--wait-timeout".to_string());
78-
cmd_parts.push(command.wait_timeout.as_secs().to_string());
76+
if command.wait {
77+
cmd_parts.push("--wait".to_string());
78+
cmd_parts.push("--wait-timeout".to_string());
79+
cmd_parts.push(command.wait_timeout.as_secs().to_string());
80+
}
7981

8082
let exec = ExecCommand::new(cmd_parts)
8183
.with_cmd_ready_condition(CmdWaitFor::exit_code(0))

testcontainers/src/compose/client/local.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ impl ComposeInterface for LocalComposeCli {
5151
cmd.arg("--pull").arg("always");
5252
}
5353

54-
cmd.arg("--wait")
55-
.arg("--wait-timeout")
56-
.arg(command.wait_timeout.as_secs().to_string());
54+
if command.wait {
55+
cmd.arg("--wait")
56+
.arg("--wait-timeout")
57+
.arg(command.wait_timeout.as_secs().to_string());
58+
}
5759

5860
for (key, value) in &command.env_vars {
5961
cmd.env(key, value);

testcontainers/src/compose/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ pub struct DockerCompose {
142142
remove_images: bool,
143143
build: bool,
144144
pull: bool,
145+
wait: bool,
145146
services: HashMap<String, RawContainer>,
146147
env_vars: HashMap<String, String>,
147148
wait_strategies: HashMap<String, WaitFor>,
@@ -244,6 +245,7 @@ impl DockerCompose {
244245
env_vars: self.env_vars.clone(),
245246
build: self.build,
246247
pull: self.pull,
248+
wait: self.wait,
247249
})
248250
.await?;
249251

@@ -353,6 +355,16 @@ impl DockerCompose {
353355
self
354356
}
355357

358+
/// Control whether docker compose waits for all services to be healthy before returning (default: true).
359+
///
360+
/// Set to `false` when using one-shot containers (e.g., init or migration containers)
361+
/// that exit after completing their task, as `--wait` would otherwise time out.
362+
/// When disabled, use [`DockerCompose::with_wait_for_service`] for per-service readiness.
363+
pub fn with_wait(mut self, wait: bool) -> Self {
364+
self.wait = wait;
365+
self
366+
}
367+
356368
/// Remove volumes when dropping the docker compose or not (removed by default)
357369
pub fn with_remove_volumes(&mut self, remove_volumes: bool) -> &mut Self {
358370
self.remove_volumes = remove_volumes;
@@ -376,6 +388,7 @@ impl DockerCompose {
376388
remove_images: false,
377389
build: false,
378390
pull: false,
391+
wait: true,
379392
services: HashMap::new(),
380393
env_vars: HashMap::new(),
381394
wait_strategies: HashMap::new(),
@@ -747,4 +760,26 @@ mod tests {
747760

748761
test_compose_client(compose, "containerised").await
749762
}
763+
764+
#[tokio::test]
765+
async fn test_compose_with_wait_disabled() -> anyhow::Result<()> {
766+
let _ = pretty_env_logger::try_init();
767+
768+
let path = PathBuf::from(format!(
769+
"{}/tests/test-compose.yml",
770+
env!("CARGO_MANIFEST_DIR")
771+
));
772+
773+
let mut compose = DockerCompose::with_local_client(&[path.as_path()]).with_wait(false);
774+
775+
compose.up().await?;
776+
777+
assert_eq!(compose.services().len(), 2, "Should have 2 services");
778+
assert!(compose.service("hello1").is_some());
779+
assert!(compose.service("hello2").is_some());
780+
781+
compose.down().await?;
782+
783+
Ok(())
784+
}
750785
}

0 commit comments

Comments
 (0)