Skip to main content
Mac users run into two separate issues with the course containers. First, Docker runs inside a Linux virtual machine and cannot reach Apple’s Metal framework, so PyTorch uses the CPU even on an M-series Mac. Second, graphical ROS tools such as Gazebo and RViz2 need XQuartz to display their windows. This page walks through the practical options for both cases. For general container setup, see Docker containers.

PyTorch native install

Installing PyTorch directly on macOS lets it use the GPU through Apple’s Metal Performance Shaders backend. PyTorch calls this device mps.

Setup

You need Python and uv for this setup. If either is missing, start with the Python and uv guide. Once uv works in your terminal, clone the repository for your course and install its dependencies:
The standard Apple Silicon build of PyTorch already includes Metal support, so there is no extra GPU package to install. You also do not need CUDA; CUDA is for NVIDIA GPUs.

Selecting the device

It is better to detect the available device than to hard-code one. This small check works on an Apple Silicon Mac, a CUDA machine, and Colab:
On an M-series Mac, the result should be mps. If you see cpu, check whether you are running inside a container or using a PyTorch build without Metal support.

When an operation is not supported

The Metal backend does not yet support every PyTorch operation. If your model uses one of them, PyTorch stops and names the unsupported operator. You can allow that operation to fall back to the CPU:
Add the variable to your shell profile if you need it regularly. A model with many fallbacks may still be slow because it repeatedly moves tensors between the GPU and CPU. See the MPS backend documentation for current details.

A note about course notebooks

Some course notebooks check for cuda but not mps, so they may still use the CPU after you finish this setup. Replacing their device-selection code with the example above is usually enough to fix the problem. If you find one, please tell us in Discord so we can correct the notebook as well.

Robotics on a Mac

For robotics coursework, start with the ROS container. ROS 2 does not officially support macOS, and the project does not publish macOS binaries. The container avoids that problem by running ROS 2 on Linux, the platform the course is built and tested on. If the container does not work well on your Mac, you have three alternatives. An Ubuntu virtual machine most closely follows the course book, RoboStack provides prebuilt Jazzy packages for Apple Silicon, and a community Homebrew tap offers a native installation. We have not tested these alternatives ourselves, so expect to do some troubleshooting if you choose one.

ROS container

This is the setup we support for the course. The robotics work lives in the turtlebot-maze repository, which is also listed under Starter repos. The repository includes its own Compose file. From its root directory, run:
RViz2 and Gazebo need XQuartz to display their windows on macOS:
After installing, open XQuartz, go to Preferences > Security, and enable Allow connections from network clients. Then allow connections:
If you would rather avoid XQuartz, turtlebot-maze includes a foxglove-bridge service. It streams the same ROS topics to your browser over a WebSocket and does not use X11:
Open ws://localhost:8765 in Foxglove, then load the layout from the repository’s foxglove/ directory. This is often the easier option on a Mac.

Ubuntu VM

Assignment 1 uses Edouard Renard’s ROS 2 from Scratch. In chapter 2, the book installs Ubuntu 24.04 in a virtual machine before adding ROS 2. Because ROS 2 Jazzy targets Ubuntu 24.04, following the book gives you an environment close to the one used for this course. There are two important limitations. Be sure to download the ARM64 build of Ubuntu; running the amd64 version through x86 emulation is much slower on an M-series Mac. The virtual machine also cannot use the Mac’s GPU, so Gazebo relies on software rendering and may struggle with more complex worlds. UTM is a free, QEMU-based virtual machine app that runs ARM64 Linux on Apple Silicon. Its paid Mac App Store version is the same application and helps fund development; you do not need to buy it. VMware Fusion and Parallels are also suitable. A virtual machine uses more disk space and memory than a container and takes longer to start. As assignment 1 suggests, stay with Docker if it is working well. The VM is a useful fallback when it is not.

RoboStack

RoboStack packages ROS for conda-style environments. Instead of installing ROS across your whole system, you create a separate environment for the project. RoboStack includes Jazzy, the ROS 2 distribution used in this course. The robostack-jazzy channel includes Apple Silicon packages for osx-arm64, including ros-jazzy-desktop. A basic setup with Pixi looks like this:
The main difficulty is adapting the coursework. turtlebot-maze assumes that you will use its Compose file. With RoboStack, you must configure and launch the nodes yourself instead of running docker compose up. That adds more ROS setup than the first assignment is meant to cover, but it can be a useful experiment after you have completed the assignment.

Homebrew tap

We have not tested this.
A community Homebrew tap provides ROS 2 Jazzy for macOS without a container. It was announced in June 2026.
The tap includes Gazebo Harmonic (gz-sim8), ros2_control, MoveIt 2, and Nav2. Because these run directly on macOS, this approach avoids both Docker and XQuartz. We have not tested this route. The tap is maintained by the community, and there is no official macOS release of ROS 2 to fall back on if something breaks. Choose it only if you are comfortable diagnosing installation problems yourself. The container remains the safer option because it runs ROS 2 on a supported Linux platform.