# How to Use mise for Docker Development: System Installs and OCI Workflows

> Master Docker development with mise. Install it globally or use its OCI backend for streamlined container workflows directly from your mise.toml. Simplify your Docker setup today.

- Repository: [jdx/mise](https://github.com/jdx/mise)
- Tags: how-to-guide
- Published: 2026-08-09

---

**Use mise in Docker by installing it via the official installer script, configuring shared directories like `MISE_DATA_DIR`, and running `mise install --system` to make tools available globally. For ephemeral workflows, enable the experimental OCI backend to build, run, and push container images directly from your [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) configuration without maintaining separate Dockerfiles.**

mise is a fast, cross-platform version manager designed to handle toolchains inside Docker containers as seamlessly as on physical hosts. According to the jdx/mise source code, the tool manages **shims**, **install paths**, and **environment variables** within containers through its core CLI entry point at [`src/main.rs`](https://github.com/jdx/mise/blob/main/src/main.rs) and dedicated OCI modules in `src/oci/`. This guide demonstrates how to provision reproducible development environments using both traditional Dockerfile-based installations and the experimental OCI commands.

## How mise Integrates with Docker Containers

When running inside a container, mise treats the environment as a standard host while respecting Docker-specific constraints around user permissions and filesystem layouts. The implementation spans several key components in the codebase:

- **[`src/main.rs`](https://github.com/jdx/mise/blob/main/src/main.rs)** – The CLI entry point that parses sub-commands like `docker`, `oci`, and `install`, forwarding execution to the appropriate backends.
- **[`src/oci/builder.rs`](https://github.com/jdx/mise/blob/main/src/oci/builder.rs)** – Handles the creation of OCI image layouts from [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) configurations, including layer generation and package resolution.
- **[`src/oci/docker_archive.rs`](https://github.com/jdx/mise/blob/main/src/oci/docker_archive.rs)** – Streams OCI layouts into Docker via the `docker load` command.
- **[`src/toolset/mod.rs`](https://github.com/jdx/mise/blob/main/src/toolset/mod.rs)** – Manages tool resolution and writes shims to the appropriate install directories, supporting both per-user and system-wide installations.
- **[`src/config/mod.rs`](https://github.com/jdx/mise/blob/main/src/config/mod.rs)** – Expands environment variables like `MISE_DATA_DIR` and `MISE_SYSTEM_DATA_DIR` that control where tools persist in containerized environments.

Inside a container, mise operates through four primary stages: installation via the official script, configuration of shared directories to avoid conflicts with mounted home folders, system-wide tool installation using the `--system` flag, and optional OCI workflow execution for temporary runtime environments.

## Installing mise in a Dockerfile

The standard approach embeds mise directly into your image during the build process. The official Docker cookbook in the repository recommends setting standardized environment variables before installation to ensure tools are stored in shared locations rather than the container's home directory.

```dockerfile

# Based on docs/mise-cookbook/docker.md (lines 7-26)

FROM debian:13-slim

RUN apt-get update && \
    apt-get -y --no-install-recommends install \
        sudo curl git ca-certificates build-essential && \
    rm -rf /var/lib/apt/lists/*

ENV MISE_DATA_DIR="/mise"
ENV MISE_CONFIG_DIR="/mise"
ENV MISE_CACHE_DIR="/mise/cache"
ENV MISE_INSTALL_PATH="/usr/local/bin/mise"
ENV PATH="/mise/shims:$PATH"

RUN curl https://mise.run | sh

```

Build and run the container to verify the installation:

```bash
docker build -t debian-mise .
docker run -it --rm debian-mise

```

Setting `MISE_DATA_DIR` to `/mise` ensures tool installations persist in a shared volume that remains accessible regardless of which user runs commands inside the container.

## Managing System-Wide Tools

By default, mise installs tools to the user's home directory, which causes conflicts when containers mount host home folders. Use the `--system` flag to install tools globally under `/usr/local/share/mise/installs`, making them available to all users.

```dockerfile

# Based on docs/mise-cookbook/docker.md (lines 60-62)

RUN mise install --system node@26 python@3.15

```

After the container starts, verify system-wide availability:

```sh
$ mise ls
node    26.0.0 (system)
python  3.15.0 (system)

```

The `--system` flag triggers the logic in [`src/toolset/mod.rs`](https://github.com/jdx/mise/blob/main/src/toolset/mod.rs) to write binaries to the system data directory rather than the user-specific path. You can further customize this behavior by setting `MISE_SYSTEM_DATA_DIR` or `MISE_SHARED_INSTALL_DIRS` environment variables before running install commands.

## Using Experimental OCI Commands

For scenarios requiring ephemeral environments without pre-built images, mise supports experimental OCI commands that build and run containers directly from your [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml). Enable these features by setting `MISE_EXPERIMENTAL=1`.

### Building OCI Images from mise.toml

The `mise oci build` command creates an OCI-compliant image layout from your current configuration, optionally including bootstrap packages defined in `[bootstrap.packages]`:

```sh
MISE_EXPERIMENTAL=1 mise oci build -o ./img

```

The [`src/oci/builder.rs`](https://github.com/jdx/mise/blob/main/src/oci/builder.rs) module handles layer generation, while [`src/oci/docker_archive.rs`](https://github.com/jdx/mise/blob/main/src/oci/docker_archive.rs) manages the streaming logic that loads the image into Docker's local registry.

### Running Temporary Containers

Execute commands in reproducible environments without maintaining a Dockerfile using `mise oci run`:

```sh

# Based on docs/dev-tools/mise-oci.md (lines 108-114)

MISE_EXPERIMENTAL=1 mise oci run -e DEBUG=1 \
    --volume "$PWD:/work" -w /work -- npm test

```

This command performs three steps: building the OCI layout from [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml), streaming it to `docker load`, and executing `docker run` with the specified volume mounts and working directory. The container is automatically removed after execution completes.

### Pushing to Registries

Push custom development images to container registries using the `oci push` command, which automatically detects credentials from `~/.docker/config.json` or `~/.config/containers/auth.json`:

```sh

# Based on docs/dev-tools/mise-oci.md (lines 219-220)

mise oci build -o ./img
mise oci push --image-dir ./img ghcr.io/me/devenv:v1

```

## Handling libc in Minimal Base Images

When building minimal containers using `scratch` or distroless bases, mise may fail to detect the correct C library implementation. Explicitly set the `libc` environment variable in your [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) to ensure mise selects compatible binary variants:

```toml

# mise.toml (example)

[env]
libc = "glibc"

```

This configuration ensures that tools dependent on specific libc implementations receive the correct binaries during installation, particularly when the container lacks the filesystem markers mise typically uses for detection.

## Summary

- **Install mise** in Docker by curling the installer script and setting `MISE_DATA_DIR` to a shared path like `/mise` to avoid home-directory conflicts.
- **Use `--system`** with `mise install` to write tools to `/usr/local/share/mise/installs`, making them available globally inside the container.
- **Enable OCI workflows** by setting `MISE_EXPERIMENTAL=1` to build temporary images directly from [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) using `mise oci build` and `mise oci run`.
- **Explicitly configure `libc`** in [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml) when using minimal base images to ensure correct binary selection.
- **Reference implementation details** in [`src/oci/builder.rs`](https://github.com/jdx/mise/blob/main/src/oci/builder.rs) and [`src/toolset/mod.rs`](https://github.com/jdx/mise/blob/main/src/toolset/mod.rs) to understand how mise routes commands and manages installations in containerized environments.

## Frequently Asked Questions

### How do I prevent mise from installing tools to the home directory inside a Docker container?

Set `MISE_DATA_DIR` to a system path like `/mise` and add `/mise/shims` to `PATH` before installing mise. This configuration, defined in [`src/config/mod.rs`](https://github.com/jdx/mise/blob/main/src/config/mod.rs), redirects all tool installations and shims to the shared directory, preventing conflicts when the host's home directory is mounted into the container.

### What is the difference between `mise install` and `mise install --system` in Docker?

Standard `mise install` writes tools to `$HOME/.local/share/mise/installs`, which may be overwritten if you mount your host home directory into the container. The `--system` flag, handled by the logic in [`src/toolset/mod.rs`](https://github.com/jdx/mise/blob/main/src/toolset/mod.rs), instead writes to `/usr/local/share/mise/installs` (or the path specified by `MISE_SYSTEM_DATA_DIR`), making tools available to all container users regardless of home directory mounting.

### Do I need to write a Dockerfile to use mise with Docker?

No. While Dockerfile-based installation provides persistent development images, you can use the experimental `mise oci run` command to execute commands in temporary containers built directly from your [`mise.toml`](https://github.com/jdx/mise/blob/main/mise.toml). This workflow, implemented in [`src/oci/builder.rs`](https://github.com/jdx/mise/blob/main/src/oci/builder.rs) and [`src/oci/docker_archive.rs`](https://github.com/jdx/mise/blob/main/src/oci/docker_archive.rs), streams the OCI layout to Docker via `docker load` and executes your command without maintaining a separate Dockerfile.

### Why are the `mise oci` commands marked as experimental?

The OCI commands require `MISE_EXPERIMENTAL=1` because they rely on interaction with external container engines (Docker or Podman) through `docker load` and `docker run`, as implemented in [`src/oci/docker_archive.rs`](https://github.com/jdx/mise/blob/main/src/oci/docker_archive.rs). The API and behavior may change as the feature stabilizes, and it requires the host system to have a compatible OCI runtime installed.