ADORe Docker-Based Development Environment¶
Overview¶
The ADORe project ships a Docker-based development environment so you can:
- Develop against a reproducible ROS 2 (Jazzy) stack.
- Keep your host system relatively clean.
- Share the same setup across contributors and CI.
- Avoid permission issues by matching the container user to your host user.
- Keep your shell history and workspace state across container restarts.
This document explains how it is structured and how to use it day-to-day.
Components¶
Docker images¶
There are three main images, all configured via .docker/scripts/common.sh:
-
Base image –
adore_base:<tag>/adore_base:latest -
Built from
.docker/base/Dockerfile. - Contains OS, ROS 2 Jazzy and base APT dependencies.
-
No user mapping or developer tooling.
-
Dev image –
adore_dev:<tag>/adore_dev:latest -
Defined in
.docker/dev/Dockerfile. FROM adore_base:latest.-
Installs additional developer packages from
.docker/dev/apt.dev.txt, including e.g.:- Shell & terminal tools:
zsh,fzf,zsh-syntax-highlighting,zsh-autosuggestions,htop,tree,bat,ripgrep,gdb. - ROS tools:
ros-jazzy-rqt,ros-jazzy-rqt-common-plugins,ros-jazzy-foxglove-bridge,ros-jazzy-ros2trace,ros-jazzy-tracetools-analysis. - Tracing & debugging:
babeltrace,lttng-modules-dkms. - X11 utilities & libraries:
x11-apps,libx11-6,libxext6,libxrender1,libxtst6,libxi6,libgl1,mesa-utils,x11-utils. - Web & misc:
python3-flask,python3-flask-cors,jq. - Installs the Helix editor (
hx) and setsHELIX_RUNTIME. - Installs Oh My Zsh (non-interactive) and configures zsh as the default shell.
- Configures ccache and a large, persistent zsh history.
- Creates or renames a non-root user that matches your host UID/GID.
- Shell & terminal tools:
-
CI image –
adore_ci:<tag>/adore_ci:latest -
Built from
.docker/ci/Dockerfile. - Used by CI and docs helpers (e.g.
just docs,just ci). - Not required for basic development, but available via
Justfilerecipes.
Each image is tagged with both :latest and a content-addressed tag based on:
where GIT_HASH is the short git commit hash of the repo, and ARCH is the machine architecture.
Scripts and helpers¶
.docker/dev/Dockerfile¶
Key behavior of the dev image:
-
Apt dependencies
-
Copies
.docker/dev/apt.dev.txtinto the image and installs everything viaapt-get. -
Helix
-
Downloads a specific Helix release, unpacks it into
/opt/helix. - Adds
/usr/local/bin/hxsymlink. - Sets
HELIX_RUNTIME=/opt/helix/runtimein/etc/profile. -
User mapping
-
Build args:
USERNAME(defaultdeveloper),USER_UID(default 2001),USER_GID(default 2001). -
At build time:
- If a user already exists with
USER_UID, it is renamed to${USERNAME}and its home directory moved to/home/${USERNAME}while the group is renamed accordingly. - Otherwise a new user
${USERNAME}is created with that UID/GID and/usr/bin/zshas the shell. - The
USERinstruction switches to${USERNAME}for the rest of the Dockerfile and at runtime. - Workspace & ccache
- If a user already exists with
-
Sets
WORKSPACE="/home/${USERNAME}/adore"andWORKDIR ${WORKSPACE}. -
Configures ccache via env vars:
CCACHE_DIR="${WORKSPACE}/.cache/ccache"CC="/usr/lib/ccache/gcc"CXX="/usr/lib/ccache/g++"- Zsh configuration
-
Appends to
${USERNAME}’s.zshrc:HISTFILE=~/adore/.zsh_historyHISTSIZE=100000,SAVEHIST=100000setopt HIST_IGNORE_DUPS,HIST_REDUCE_BLANKS,SHARE_HISTORY,INC_APPEND_HISTORY- Ensures the workspace directory and history file exist and are owned by
${USERNAME}. - ROS & overlay auto-sourcing
-
Appends a block to
.zshrcthat:- Sources
/opt/ros/${ROS_DISTRO:-jazzy}/setup.zshif it exists. -
Sources the local colcon workspace overlay, preferring:
-
$HOME/adore/.colcon_workspace/install/local_setup.zsh - then
$HOME/adore/.colcon_workspace/install/setup.zsh. - Default command
- Sources
-
The container entrypoint is a login zsh shell:
.docker/scripts/build_dev.sh¶
Builds the base and dev images on the host:
-
Loads
common.shand asserts it is running on the host (viarequire_host). -
Switches to
$WORKSPACE_ROOT. -
If
adore_base:latestdoes not exist, builds it:
- Always builds the dev image:
The build args ensure the dev image’s user matches your host user, avoiding permission issues on the bind-mounted workspace.
.docker/scripts/run_dev.sh¶
Starts or attaches to the dev container (host-side script):
-
Loads
common.shand enforces host execution (require_host). -
Ensures the dev image exists:
-
If
adore_dev:latestis missing, callsbuild_dev.sh. -
Sets
IMAGE="${DOCKER_DEV_IMAGE_LATEST}"andCONTAINER_NAME="${DOCKER_CONTAINER_NAME}". -
If a container with that name is running:
-
Clears the screen, prints
dev_greeting, and runs: -
Then exits (you’re now attached to the existing container).
-
If a container with that name exists but is stopped, it is removed.
-
Ensures host-side zsh history file exists:
- Starts a fresh dev container:
- Before you get the shell prompt, the script clears the terminal and prints the
dev_greetingbanner.
Key points:
- Host networking (
--network host) simplifies ROS 2 discovery and interaction with host services. - X11 support is set up via the
/tmp/.X11-unixbind mount andDISPLAY/QT_X11_NO_MITSHM. - Shell history is persisted on the host (
.zsh_historyin the repo) and reused across containers.
.docker/scripts/setup_colcon_src.sh¶
Keeps .colcon_workspace/src in sync with the top-level package layout:
- Expects categories under the repo root:
-
For each category:
-
If
${WORKSPACE_ROOT}/${category}does not exist:- Prints a warning and skips it.
-
If
.colcon_workspace/src/${category}is already a symlink: -
Verifies it points at the expected relative path (
../../${category}). - Leaves it alone or updates it if the target changed.
-
If a non-symlink node exists at that path:
-
Prints an error and exits, to avoid clobbering user files.
-
Otherwise:
-
Creates the symlink:
just dev always runs setup_colcon_src first, so the colcon workspace reflects whatever packages are present at the top level.
Justfile integration¶
The Justfile in the repo root ties all of this together.
Important recipes related to the dev environment:
-
Entry points
-
justorjust help– list all available recipes. just dev– ensure colcon symlinks, then run the dev container.-
Docker images
-
just build_dev– build base + dev images (host). just clean_images– remove local ADORe images.just save/just load– save/load dev/CI images as tarballs.-
Workspace cleanup
-
just clean_ws– delete.colcon_workspace/{build,install,log}. just clean–clean_images+clean_ws.just clean_build– clean the workspace and then build.-
Colcon builds & tests (host or inside the dev container)
-
just build– build the entire.colcon_workspace. just test_ws– runcolcon test(skipping vendor packages) +colcon test-result.just build_scenarios,just build_nodes, etc. – targeted builds for subsets of packages.-
Tools & GUI
-
just gui– run the ADORe scenario launcher. just edit_roads– road network editor.just lichtblick– Lichtblick visualization wrapper.-
Docs & CI
-
just docs– build documentation inside the CI image. just ci– run a CI-like test/docs pipeline locally.
You can run these either on the host (if you have ROS and dependencies installed) or inside the dev container (recommended, since that environment is controlled and consistent).
Container layout and runtime environment¶
Once you’re inside the dev container via just dev or .docker/scripts/run_dev.sh:
- Working directory:
/home/<user>/adore(the mounted repo). - Colcon workspace:
/home/<user>/adore/.colcon_workspace. - Sources:
.colcon_workspace/src(symlinks back to top-level ADORe directories). - Default shell:
zshwith Oh My Zsh and custom history options. - Editor:
hx(Helix) is available. -
ROS:
-
/opt/ros/$ROS_DISTRO/setup.zshis sourced automatically. - If you have built the workspace, the overlay under
.colcon_workspace/installis also sourced automatically by.zshrc.
All ROS tools from apt.dev.txt are ready to use: rqt, ros2trace, foxglove-bridge, etc.
Typical workflow¶
- Clone the repo (on your host machine):
- Start the dev container:
This will:
- Set up
.colcon_workspace/srcsymlinks. - Build the base/dev images if needed.
- Start the container or attach to it if already running.
-
Drop you into a login zsh shell inside
adore_dev. -
Build the workspace (inside the container):
Or:
- Run tests:
- Run tools and GUIs:
-
Stop / restart later
-
Simply exit the shell to stop the container (because it was started with
--rm). - Next time, run
just devagain; your workspace state and shell history are preserved.
Summary¶
The ADORe Docker development environment provides:
- A consistent ROS 2 Jazzy-based stack with all necessary tools.
- A user inside the container that matches your host user, avoiding permissions pain.
- A colcon workspace layout centered on
.colcon_workspacewith symlinks mirroring the repo. - Simple host-side entrypoints (
just dev,.docker/scripts/run_dev.sh) to start or attach to a ready-to-use dev shell. - Persistent shell history and a curated CLI experience tuned for day-to-day ADORe development.