Skip to content

🤖 fix: align Docker server MUX_ROOT persistence contract #3802

Description

@alecsg77

Summary

The Docker server image currently creates and mounts /root/.mux, but exports MUX_HOME=/root/.mux. The application resolver (getMuxHome() in src/common/constants/paths.ts) recognizes MUX_ROOT, not MUX_HOME.

The root image works today only because os.homedir() resolves to /root. Under docker run --user ..., that implicit fallback can select a different home directory, bypass the mounted volume, or fail on writes.

Proposed contract

  • Make MUX_ROOT the explicit Docker image contract: set MUX_ROOT=/root/.mux in Dockerfile.
  • Retain the root default and the existing docker-compose.yml persistence target, mux-data:/root/.mux, so existing volumes and bind mounts remain compatible.
  • Do not add MUX_HOME as an application alias: MUX_ROOT is the existing resolver override and dual-variable precedence would create an unnecessary compatibility surface.
  • Treat non-root execution as an explicit operator configuration: users running the image with --user must provide a writable, mounted MUX_ROOT path with compatible ownership. The image should not infer a different home, chown mounted volumes, or migrate state.

Implementation and validation

  1. Replace the Dockerfile MUX_HOME environment declaration with MUX_ROOT=/root/.mux, retaining directory creation and the current volume location.
  2. Add a behavioral unit test in src/common/constants/paths.test.ts for getMuxHome() proving MUX_ROOT is returned exactly and restoring mutated environment variables afterward. If practical, also prove MUX_HOME alone does not alter resolution.
  3. Run the focused test, Dockerfile lint/static checks, and a local image build/smoke test when Docker is available.

Existing CI already has Docker image startup smoke coverage in .github/workflows/pr.yml, but it checks health/version rather than persistence-root resolution. The resolver test should protect the actual contract without adding a brittle filesystem-only container assertion.

Context

A prior search found no exact duplicate. #3699 may be a user-facing symptom but is unconfirmed. PR #849 introduced the current image convention; PR #1587 is related precedent for non-root runtime handling.


Generated with mux • Model: openai:gpt-5.6-terra • Thinking: high • Cost: $0.04

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions