Got Tired of Bad Setups, So I Built a Modern Docker Env for MuJoCo MPC on Windows
Published:
If you’re a dev working in robotics, you’ve probably wanted to check out Google DeepMind’s MuJoCo MPC. It’s a fantastic toolkit. But if you’re on a Windows machine, you’ve probably also hit a wall trying to get it running. I know I did.
The Problem: VMs are Clunky, Old Dockers are Broken
My first instinct was to spin up a Linux VM. That was a dead end. It was slow, and trying to get GPU passthrough working correctly with the simulator’s GUI was an absolute nightmare.
So, I turned to Docker. Seemed like the right tool for the job. But every guide and existing Dockerfile I found on the web felt obsolete. Most were built on old CUDA 11.x versions, required a bunch of manual tweaks, or just didn’t play nice with a modern WSL 2 setup on Windows. The goal is to do research, not spend a week debugging someone else’s environment.
The Solution: A Clean Build for CUDA 12
I was frustrated, so I decided to build the solution I wished I’d found in the first place. My goals were simple:
- Build on a recent NVIDIA CUDA 12.2 image.
- Make it work seamlessly with Docker Desktop’s WSL 2 backend for GPU support.
- Provide a straightforward way to get the GUI working on the Windows host.
- Script the entire thing in one
Dockerfile
for a reproducible build.
What I ended up with is a setup that just works. It combines the power of WSL 2 with a simple Windows X Server (VcXsrv) to give you a native-like experience. You can find the complete Dockerfile and all instructions in the GitHub repository. Hope it helps you get straight to the fun part.
The Nitty-Gritty: How it Works
The whole setup boils down to two key pieces of code.
1. The Dockerfile
: The Build Script
This is the recipe for the entire environment. It’s responsible for layering everything we need on top of a clean NVIDIA base image.
It starts with a solid foundation: nvidia/cuda:12.2.2-cudnn8-devel-ubuntu22.04
. From there, it uses apt-get
to pull in all the C++ build essentials and X11 libraries (libglfw3
, libxrandr-dev
, etc.) and then uses pip
to install the Python dependencies like mujoco
and gymnasium
. You don’t have to install a single thing inside the container manually; it’s all scripted.
# CUDA-enabled MuJoCo 3.x (Python ≥ 3.10) – CUDA ≥ 12.2
ARG cuda_docker_tag="12.2.2-cudnn8-devel-ubuntu22.04"
FROM nvidia/cuda:${cuda_docker_tag}
ENV DEBIAN_FRONTEND=noninteractive \
PYTHONUNBUFFERED=1 \
MUJOCO_GL=egl \
LANG=C.UTF-8
# Install all system-level dependencies for C++ and Python
RUN apt-get update && \
apt-get install -y --no-install-recommends \
python3 python3-pip git build-essential \
libosmesa6-dev libgl1-mesa-glx libglfw3 libglew-dev \
libxrandr2 libxinerama1 libxcursor1 ...
# Install Python packages
RUN python -m pip install --upgrade --no-cache-dir pip setuptools wheel && \
pip install --no-cache-dir \
"mujoco>=3.3" \
glfw \
gymnasium[robotics] \
...
# ... SSH and Entrypoint configuration
2. The docker run
command: The Key
Once the image is built, this one-liner is what brings it to life.
docker run --gpus all --env NVIDIA_DRIVER_CAPABILITIES=all -it --name mjpc_env -e DISPLAY=host.docker.internal:0.0 -v /tmp/.X11-unix:/tmp/.X11-unix mujoco-py310 /bin/bash
Let’s break down the important flags:
--gpus all
: The magic flag. This passes your host’s NVIDIA GPU directly into the container.-e DISPLAY=host.docker.internal:0.0
: This is the networking trick. It tells GUI applications inside the container to send their visuals to the display located athost.docker.internal:0.0
, which is our VcXsrv instance running on Windows.-v /tmp/.X11-unix:/tmp/.X11-unix
: Mounts the necessary Unix socket for X11 forwarding to work.
Get it Running
I’ve detailed everything in the README
, but here’s the tricks:
- Prep your Windows host: Make sure Docker Desktop (using the WSL 2 backend) and VcXsrv are installed and running. Critically, when you launch VcXsrv, you must disable access control.
- Build the image:
docker build -t mujoco-py310 .
- Launch the container: Use the
docker run
command above. - Compile MJPC: Inside the container, clone the
mujoco_mpc
repo,mkdir build && cd build
,cmake ..
, andmake -j"$(nproc)"
. - Test it: Run
./bin/mjpc --task cartpole
. If everything is set up right, the simulation window will pop up on your Windows desktop.
I’m sharing this to hopefully save other developers the headache I went through. Environment setup is a tedious chore that gets in the way of the actual work. This repo is my attempt to script that chore away. Check out the README
for the full walkthrough and troubleshooting. Hope it helps you get straight to the fun part.