diff --git a/src/build/remote.ts b/src/build/remote.ts index 368b826..6aec392 100644 --- a/src/build/remote.ts +++ b/src/build/remote.ts @@ -25,8 +25,12 @@ export const captureRemote = async ( cmd: string ): Promise => { try { + // stdin: 'ignore' (≈ ssh -n), never 'inherit'. Concurrent ssh calls that + // inherit the shared interactive stdin fight over fd 0 and block — the + // classic "parallel ssh eats stdin" deadlock that stalls prefetch + // (mkdir/file-check) for later recipes while an earlier build streams. const { stdout } = await execa('ssh', [target, cmd], { - stdin: 'inherit', + stdin: 'ignore', stderr: 'inherit', }) return stdout @@ -129,7 +133,9 @@ export const streaming = async ( return } const proc = execa(cmd, args, { - stdin: 'inherit', + // ignore (not inherit): a long packer stream must not hold the shared + // stdin and starve concurrent prefetch ssh calls. See captureRemote. + stdin: 'ignore', stdout: 'pipe', stderr: 'pipe', })