Skip to content

Integrating mise Shims into Dev Container PATH #11

Description

@raulcastillabravo

Objective

The goal is to provide a seamless experience where tools managed by mise (such as aws and terraform) are automatically available in all execution contexts within a Dev Container:

  1. Interactive Terminal: When a user opens a terminal and types a command.
  2. Post-Create Command: Orchestrated scripts running during container initialization (postCreateCommand).
  3. Automated Tests: Commands executed via docker compose exec or similar non-interactive methods from outside/inside.

Experiments & Results

1. Persistent Activation via ~/.bashrc

  • Method: Appending eval "$(mise activate bash)" to the user's .bashrc.
  • Result: Works for interactive shells only.
  • Why it failed for automation: Non-interactive shells (used by postCreateCommand and docker compose exec) do not source the .bashrc profile, leaving the PATH without the necessary shims.

2. Using mise exec as a Prefix

  • Method: Running every tool command as mise exec -- [command].
  • Result: Functionally correct but high boilerplate.
  • Why it failed (Experience): It feels "unnatural" for an MVE. Users expected to use standard CLI commands. It also complicates test orchestration fixtures.

3. Dynamic PATH via containerEnv (The ${containerEnv:PATH} Attempt)

  • Method: Defining the environment variable in devcontainer.json using the built-in variable expansion:
    "containerEnv": {
      "PATH": "/home/vscode/.local/share/mise/shims:${containerEnv:PATH}"
    }
  • Result: Critical Failure. The container crashes immediately and fails to start.
  • Why it failed:
    • If ${containerEnv:PATH} is empty or fails to resolve during the initial container setup, the PATH is effectively overwritten with only the mise shim path.
    • Since mise is not yet installed (or the directory is empty), the container loses access to crucial system binaries like /bin/sleep or /bin/sh.
    • The "Dev Container" service dies because it cannot execute its entrypoint command (sleep infinity).

4. Hardcoding the Complete PATH (Current Workaround)

  • Method: Manually listing every standard system path along with the mise shims:
    "containerEnv": {
      "PATH": "/home/vscode/.local/share/mise/shims:/usr/local/py-utils/bin:/usr/local/python/current/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    }
  • Result: Success. The container starts, and shims are available everywhere (interactive and non-interactive).
  • The Problem: This is high-maintenance. It depends on internal paths of the mcr.microsoft.com/devcontainers/python image. If the base image updates or changes its internal structure, the MVE will break unexpectedly.

Challenge / Goal

We need a way to prepend to the PATH in a Dev Container environment without having to hardcode the entire system path.

The ideal behavior would be similar to how features work, which can modify environment variables without wiping out the defaults. Is there a safe way to resolve ${containerEnv:PATH} or a standard hook that runs before postCreateCommand but after tool installation that persists the PATH for non-interactive sessions?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions