ROS is built for Ubuntu, but many robotics students work on M-series MacBooks. This repo compares four ways to run ROS 1 and ROS 2 on an Apple Silicon Mac and records the errors I actually hit, with their root causes and fixes. It ends with a real project: building and running the KUKA KMR iiwa ROS stack in Docker.
Most of the detailed notes are written in Chinese (中文). This README is the English overview and index.
| Method | Result | Good for | Main pain points |
|---|---|---|---|
| Ubuntu 24.04 ARM VM + ROS 2 Jazzy (VMware / Parallels / UTM) | ✅ Smoothest | Full Linux, RViz, day-to-day development | Needs RAM (8 GB+ for Gazebo) and ~20 GB of disk |
Docker Desktop (ros:noetic, ros:humble, osrf/ros:noetic-desktop-full) |
✅ CLI · |
Reproducible environments, several distros side by side | GPG key expiry, X11 forwarding, OpenGL under amd64 emulation (Gazebo GUI crashes) |
| FishROS one-line installer (鱼香ROS) | Quick installs inside an Ubuntu VM | Script is opaque when it fails; doesn't run on macOS itself | |
| Native macOS build (ROS 2 Rolling from source) | ❌ Gave up | Not recommended | Python 3.12 vs 3.11 conflicts, launch_testing and C++ packages failing in colcon build |
Recommendation: use a VM for anything that needs RViz/Gazebo, and Docker for headless nodes or for trying another distro quickly.
# inside an Ubuntu 24.04 (arm64) VM
sudo apt update && sudo apt install -y locales curl
sudo locale-gen en_US en_US.UTF-8 && sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
-o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" \
| sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt update && sudo apt install -y ros-jazzy-desktop-full python3-colcon-common-extensions
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc && source ~/.bashrc
ros2 run demo_nodes_cpp talker # terminal 1
ros2 run demo_nodes_py listener # terminal 2Full walkthrough: Troubleshooting ROS Installation on Mac, method 4
# on the Mac (one time): install XQuartz, enable
# XQuartz → Settings → Security → "Allow connections from network clients"
brew install socat
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" # keep this terminal open
open -a XQuartz
docker run --platform=linux/amd64 -it --name ros_gui \
-e DISPLAY=$(ipconfig getifaddr en0):0 \
-v ~/ros1_ws:/root/ros1_ws \
osrf/ros:noetic-desktop-full
# inside the container: check the X11 path first
apt update && apt install -y x11-apps mesa-utils && xeyesIf 3D apps fail with libGL error: failed to load driver: swrast, install the Mesa packages and set LIBGL_ALWAYS_SOFTWARE=1. See Docker GUI troubleshooting.
| ROS 2 talker / listener across two containers | KMR iiwa MoveIt move_group running in Docker |
| turtlesim forwarded to macOS via XQuartz | glxgears with software OpenGL |
With amd64 images under emulation, gzclient (Gazebo GUI) and sometimes RViz crash with Segmentation fault, exit code 139, even when X11 forwarding works (xeyes opens). The cause is OpenGL support under QEMU on ARM Macs, not your project.
The physics server still works headless, so you can drive the simulation through topics, MoveIt and rostopic:
roslaunch kmriiwa_gazebo kmriiwa_empty_world.launch gui:=falseFor a fully reliable Gazebo GUI, use a native x86_64 Linux machine or a cloud server.
| Error | Cause | Fix | Notes |
|---|---|---|---|
EXPKEYSIG F42ED6FBAB17C654 ... repository is not signed |
Old ROS apt key expired | Re-download ros.key into /usr/share/keyrings/ and point the source list at it |
GPG key |
Conflicting values set for option Signed-By |
Two ROS source lists with different key paths | Remove /etc/apt/sources.list.d/ros1-latest.list |
Methods |
qt.qpa.xcb: could not connect to display |
No X server / wrong DISPLAY format |
XQuartz + socat, DISPLAY=<mac-ip>:0 or host.docker.internal:0 |
GUI in Docker |
libGL error: No matching fbConfigs / swrast |
Missing Mesa software renderer | apt install mesa-utils libgl1-mesa-glx …, LIBGL_ALWAYS_SOFTWARE=1 |
GUI troubleshooting |
launch_testing package not found (native build) |
CMake picked Python 3.12 instead of 3.11 | Remove the conflicting Python, fix PATH, clean build install log |
Methods |
zsh: command not found: vcs / rosdep |
pip tools missing from the active Python | python3 -m pip install -U vcstool rosdep |
Methods |
urlopen error [Errno 8] nodename nor servname |
DNS / unstable VPN | Use a stable connection, public DNS (1.1.1.1 / 8.8.8.8) | Methods |
Could not find a package configuration file provided by "XXX" |
Missing ROS dependency | rosdep install --from-paths src --ignore-src -r -y or apt install ros-noetic-xxx |
Project example |
| Note | Topic | Language |
|---|---|---|
| Troubleshooting ROS Installation on Mac: 4 Methods | Native build, FishROS, Docker and VM compared; every error and fix | 中文 |
| ROS GPG Key Problem when using Docker | Fixing the expired ROS apt key inside a container | English |
| Docker basics (使用docker的基本语句) | Naming, entering and running containers; roscore first |
中文 |
| Starting a container (开始使用容器的指令) | Re-entering a container and sourcing a workspace | 中文 |
| Verify ROS in Docker (在docker上验证ROS的安装) | Talker/listener for ROS 1 and ROS 2; multi-container ros_master network |
中文 |
| GUI apps from Docker (在Mac主机上的Docker容器中运行GUI应用) | XQuartz + socat setup for amd64 containers | 中文 |
| Docker GUI troubleshooting (在docker中运行ros的GUI 显示问题解决) | turtlesim / RViz display errors, Mesa, VNC fallback | 中文 |
| Project example: KMR iiwa (使用ROS1的项目示例) | Mounting a catkin workspace, catkin build, MoveIt, navigation, Gazebo limits |
中文 |
├── notes/ Guides and troubleshooting write-ups (Markdown, written in Obsidian)
└── attachments/ Screenshots and screen recordings referenced by the notes
Huihang Liu · Computer Engineering, Penn State · @greenaandblue Interested in robotics, embedded systems, computer vision and autonomous systems.