Skip to content

compose: RenderEntrypointWrapper doesn't gate entrypoint/command on overrideCommand #104

Description

@bilby91

Summary

compose.RenderEntrypointWrapper (added in #103) is a faithful port of the reference devcontainers/cli generateFeaturesComposeOverrideContent, with one deliberate gap: it does not implement overrideCommand gating of the original entrypoint/command.

Reference behavior

In src/spec-node/dockerCompose.ts the CLI computes:

const userEntrypoint = overrideCommand ? [] : composeEntrypoint || (imageEntrypoint…);
const userCommand    = overrideCommand ? [] : composeCommand   || (imageCmd…);
// …emits `command: <userCommand>` only when userCommand !== composeCommand

When overrideCommand is true, both the original entrypoint and command are zeroed — the generated wrapper runs the feature entrypoints, then exec "$@" hits empty args and falls through to the while sleep 1 & wait $!; do :; done keep-alive.

Our behavior

RenderEntrypointWrapper always preserves the original entrypoint (service's entrypoint:, else the image ENTRYPOINT) and never zeroes the command or emits a command: override. We do not read cfg.OverrideCommand on the compose path at all (serviceToRunSpec also ignores it).

Why this is low priority

Per the dev container spec, overrideCommand defaults to false for Docker Compose (true only for image/Dockerfile). With it false, the reference takes the composeEntrypoint || … / composeCommand || … branches — i.e. preserves exactly what we preserve. So for the default compose case (and the DAP devcontainer this was built for), our output is behaviorally equivalent to upstream.

The only divergence is an explicit "overrideCommand": true on a compose devcontainer: upstream would drop the service command and rely on the wrapper's keep-alive; we keep the command.

Options

  • Implement overrideCommand gating in the compose path for full parity (zero entrypoint/command + emit keep-alive command when overrideCommand is true), or
  • Leave as-is and document the limitation.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions