Skip to content

feat(run): allow -i and -d together when -t is set#4989

Open
mayur-tolexo wants to merge 1 commit into
containerd:mainfrom
mayur-tolexo:feat/run-detach-interactive
Open

feat(run): allow -i and -d together when -t is set#4989
mayur-tolexo wants to merge 1 commit into
containerd:mainfrom
mayur-tolexo:feat/run-detach-interactive

Conversation

@mayur-tolexo

@mayur-tolexo mayur-tolexo commented Jun 22, 2026

Copy link
Copy Markdown

Fixes #317

nerdctl run rejected -i together with -d via a hardcoded FIXME, so the command in #317 (nerdctl run -t -d -i ...) failed.

What this does

  • Allows -i -d when -t is also set — with a TTY the containerd shim holds the pty open, so the detached container keeps a usable stdin and stays running. Unblocks the issue's exact command.
  • Without -t, returns a clear error (flags -i and -d can only be specified together with -t) instead of the FIXME.

Why not non-TTY -d -i?

nerdctl is daemonless. For a detached container, stdout/stderr use containerd binary logging; the shim's createIO picks the IO path solely from the stdout URI scheme, so a binary:// logger and a stdin FIFO can't coexist. With no daemon to hold a plain stdin pipe open, a non-TTY -d -i process reads EOF immediately. Docker supports it only because dockerd holds the FIFOs; doing so in nerdctl would need a persistent per-container IO holder (conmon-style), out of scope here.

Out of scope

  • run/create only — the same FIXME in exec/compose run is left alone.
  • Attaching to an already-detached TTY container is a separate pre-existing limitation (TerminalBinaryIO stores a binary:// stdout that attach can't reopen).

Tests

New cmd/nerdctl/container/container_run_detach_interactive_linux_test.go:

  • TestRunDetachInteractiveWithTTYrun -t -d -i runs detached and stays running.
  • TestRunDetachInteractiveWithoutTTYFailsrun -d -i (no -t) fails with the clear error (nerdctl-only; Docker supports it).

Verified locally in a Linux + containerd sandbox: gofmt, go vet, build, and the new + existing TestAttach* integration tests pass.

cc @AkihiroSuda

@mayur-tolexo

Copy link
Copy Markdown
Author

Local test results

Run in a Linux + containerd dev sandbox (Docker --privileged, overlayfs snapshotter on an ext4-backed /var/lib/containerd).

Environment

  • containerd 1.7.24
  • runc 1.1.15
  • go 1.26.4

Static checks

  • gofmt -l on changed files: clean
  • go vet ./pkg/cmd/container/ ./cmd/nerdctl/container/: clean
  • go build ./cmd/nerdctl: ok

New testsgo test ./cmd/nerdctl/container/ -run TestRunDetachInteractive -test.target=nerdctl

--- PASS: TestRunDetachInteractiveWithoutTTYFails (0.04s)
--- PASS: TestRunDetachInteractiveWithTTY (0.35s)
ok  	github.com/containerd/nerdctl/v2/cmd/nerdctl/container	0.362s

Regression — existing attach suite -run TestAttach

--- PASS: TestAttachForAutoRemovedContainer (0.43s)
--- PASS: TestAttachDetachKeys (1.34s)
--- PASS: TestAttach (1.36s)
--- PASS: TestAttachNoStdin (5.36s)
ok  	github.com/containerd/nerdctl/v2/cmd/nerdctl/container	5.379s

Manual flag matrix also verified: run -d, run -t -d, run -t -d -i all start and stay running; run -d -i (no -t) fails with flags -i and -d can only be specified together with -t.

@mayur-tolexo

Copy link
Copy Markdown
Author

Manually verified flag matrix

nerdctl run <flags> alpine <cmd> then inspect --format {{.State.Running}} (cmd = sleep 60, except the -i -d row uses cat):

flags exit code container state notes
-d 0 running unchanged
-t -d 0 running unchanged
-t -d -i 0 running enabled by this PR (issue #317 command)
-t -i -d 0 running order-independent
-i -d (no -t) 1 (not created) errors: flags -i and -d can only be specified together with -t

@mayur-tolexo mayur-tolexo force-pushed the feat/run-detach-interactive branch from 2e71957 to 14d4e2c Compare June 22, 2026 10:16
Comment thread pkg/cmd/container/create.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates nerdctl run/create flag validation to allow -i (interactive) and -d (detach) to be used together only when -t (TTY) is also set, addressing Issue #317 by removing the previous hardcoded FIXME rejection and replacing it with a clearer, behavior-based constraint.

Changes:

  • Allow -i -d when -t is enabled (TTY case).
  • Reject non-TTY -i -d with a clear error message explaining the constraint.
  • Add Linux integration tests covering both the allowed (-t -d -i) and rejected (-d -i without -t) cases.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
pkg/cmd/container/create.go Replaces the old FIXME hard-fail with a conditional validation that only rejects -i -d when -t is not set, and improves the error message.
cmd/nerdctl/container/container_run_detach_interactive_linux_test.go Adds integration tests to ensure run -t -d -i works and run -d -i fails with the expected error.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@AkihiroSuda

Copy link
Copy Markdown
Member

Please squash the commits

@mayur-tolexo mayur-tolexo force-pushed the feat/run-detach-interactive branch from 981c55e to c413000 Compare June 22, 2026 12:00
Comment thread cmd/nerdctl/container/container_run_detach_interactive_linux_test.go Outdated
Previously `nerdctl run` rejected -i with -d unconditionally via a FIXME
error. The combination is valid when -t is also given: the containerd shim
holds the pty open, so the detached container keeps a usable stdin.

Without -t, a detached interactive container cannot work in nerdctl's
daemonless model -- there is no persistent process to hold the container's
stdin open, so the process would read EOF immediately. That case now returns
a clear error instead of the FIXME.

Add integration tests for the accepted (-t -d -i) and rejected (-d -i) cases.

Signed-off-by: Mayur Das <mayur.das@neevcloud.com>
@mayur-tolexo mayur-tolexo force-pushed the feat/run-detach-interactive branch from c413000 to 4213f61 Compare June 22, 2026 12:33
@AkihiroSuda AkihiroSuda added this to the v2.3.4 milestone Jun 22, 2026

@AkihiroSuda AkihiroSuda left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

currently flag -i and -d cannot be specified together

4 participants