feat(terminal): map -i/-t docker run options to stdin_open/tty

convertDockerRunToCompose() only parsed --long flags, so the short
interactive/TTY flags were dropped. Map -i/--interactive to stdin_open
and -t/--tty to tty (and -it/-ti to both).

This lets a single Docker Image application keep STDIN open and allocate
a TTY by adding -it to its Custom Docker options. The container then
reports Config.OpenStdin=true, so the terminal's existing attach
auto-detection connects to the main process in Console mode (e.g. game
server consoles) instead of falling back to a shell.
This commit is contained in:
Aditya Tripathi committed 2026-09-06 04:37:02 +00:00
1 parent 1c7e2dfc9e
commit 62099f5a3d
2 files changed
+66

No files matched your search

+19
View File
@@ -1395,6 +1395,25 @@ function convertDockerRunToCompose(?string $custom_docker_run_options = null)
}
}
// Short interactive/TTY flags (-i, -t, -it, -ti) and their long forms are not matched by
// the long-option regex above. Map them to compose so a single-image app can keep STDIN
// open (docker -i) and/or allocate a TTY (docker -t) — required for `docker attach` to an
// interactive main process, e.g. game-server consoles.
foreach (preg_split('/\s+/', trim((string) $custom_docker_run_options)) as $token) {
if ($token === '--interactive') {
$compose_options->put('stdin_open', true);
} elseif ($token === '--tty') {
$compose_options->put('tty', true);
} elseif (preg_match('/^-[a-z]+$/', $token)) {
if (str_contains($token, 'i')) {
$compose_options->put('stdin_open', true);
}
if (str_contains($token, 't')) {
$compose_options->put('tty', true);
}
}
}
return $compose_options->toArray();
}
@@ -233,3 +233,50 @@ test('ConvertIpAndIp6Together', function () {
'ip6' => ['2001:db8::1'],
]);
});
test('ConvertInteractiveShortFlag', function () {
// -i keeps STDIN open so `docker attach` can send input (e.g. game server consoles).
expect(convertDockerRunToCompose('-i'))->toBe([
'stdin_open' => true,
]);
});
test('ConvertTtyShortFlag', function () {
expect(convertDockerRunToCompose('-t'))->toBe([
'tty' => true,
]);
});
test('ConvertInteractiveTtyCombinedShortFlag', function () {
expect(convertDockerRunToCompose('-it'))->toBe([
'stdin_open' => true,
'tty' => true,
]);
});
test('ConvertTtyInteractiveCombinedShortFlag', function () {
expect(convertDockerRunToCompose('-ti'))->toBe([
'stdin_open' => true,
'tty' => true,
]);
});
test('ConvertInteractiveTtyLongFlags', function () {
expect(convertDockerRunToCompose('--interactive --tty'))->toBe([
'stdin_open' => true,
'tty' => true,
]);
});
test('ConvertInteractiveTtyWithOtherOptions', function () {
expect(convertDockerRunToCompose('-it --cap-add SYS_ADMIN'))->toBe([
'cap_add' => ['SYS_ADMIN'],
'stdin_open' => true,
'tty' => true,
]);
});
test('DoesNotSetInteractiveTtyForUnrelatedShortFlags', function () {
// -d (detach) and other short flags without i/t must not enable stdin/tty.
expect(convertDockerRunToCompose('-d'))->toBe([]);
});