Create Overlay Docker Images
When working with MoveIt Pro, you will likely create new packages which may contain:
- New Behaviors and Objectives
- New robot configuration packages
- Descriptions and drivers for a new robot
- Novel algorithms currently not present in MoveIt Pro
For many of these applications, you can mount a user workspace directly into the MoveIt Pro Docker containers. However, there may be some use cases where this may not be sufficient, such as:
- Your workspace requires additional binary packages, where
rosdep install
,apt-get install
,pip install
, etc. is needed to build the workspace. - The hardware and/or algorithms you are working with require additional dependencies.
- You want to install additional tools for debugging during development.
Creating the Overlay Image
You can create an overlay Docker image by making a Dockerfile
at the root of your workspace.
To use this image with the moveit_pro
utility, you must ensure there is a stage named base
which installs all the needed dependencies.
This includes copying source code into the image, creating a new non-root user to that you have ownership of mounted files on the host, and installing any additional dependencies needed by your workspace.
# Specify the MoveIt Pro release to build on top of.
ARG USERNAME=studio-user
ARG USER_UID=1000
ARG USER_GID=1000
# Extend the 5.2.0 release of MoveIt Pro
FROM picknikciuser/moveit-studio:5.2.0 as base
# Create a non-root user
ARG USERNAME
ARG USER_UID
ARG USER_GID
# Copy source code from the workspace's ROS 2 packages to a workspace inside the container
ARG USER_WS=/home/${USERNAME}/user_ws
ENV USER_WS=${USER_WS}
RUN mkdir -p ${USER_WS}/src ${USER_WS}/build ${USER_WS}/install ${USER_WS}/log
COPY ./src ${USER_WS}/src
# Also mkdir with user permission directories which will be mounted later to avoid docker creating them as root
WORKDIR $USER_WS
# hadolint ignore=DL3008
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
groupadd --gid $USER_GID ${USERNAME} && \
useradd --uid $USER_UID --gid $USER_GID --shell /bin/bash --create-home ${USERNAME} && \
apt-get update && \
apt-get install -q -y --no-install-recommends sudo && \
echo ${USERNAME} ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME} && \
cp -r /etc/skel/. /home/${USERNAME} && \
mkdir -p \
/home/${USERNAME}/.ccache \
/home/${USERNAME}/.config \
/home/${USERNAME}/.ignition \
/home/${USERNAME}/.colcon \
/home/${USERNAME}/.ros && \
chown -R $USER_UID:$USER_GID /home/${USERNAME} /opt/overlay_ws/
# Install additional dependencies
# You can also add any necessary apt-get install, pip install, etc. commands at this point.
# NOTE: The /opt/overlay_ws folder contains MoveIt Pro binary packages and the source file.
# hadolint ignore=SC1091
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
. /opt/overlay_ws/install/setup.sh && \
apt-get update && \
rosdep install -q -y \
--from-paths src \
--ignore-src
# Set up colcon defaults for the new user
USER ${USERNAME}
RUN colcon mixin add default \
https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml && \
colcon mixin update && \
colcon metadata add default \
https://raw.githubusercontent.com/colcon/colcon-metadata-repository/master/index.yaml && \
colcon metadata update
COPY colcon-defaults.yaml /home/${USERNAME}/.colcon/defaults.yaml
# hadolint ignore=DL3002
USER root
Note that final steps in the Dockerfile above set up Colcon defaults by copying from a file named colcon-defaults.yaml
.
You can configure this file to control the build and test behavior of your ROS 2 packages.
Importantly, setting symlink_install: True
is necessary for syncing changes to Objectives and Waypoints between your source code and the UI.
build:
# Setting this to true is necessary for syncing changes to Objectives and Waypoints between your source code and the UI.
symlink-install: true
mixin:
# Enable ccache support
- ccache
# Multithreaded linker to speed up linking step during compilation
- lld
- compile-commands
# Debug info and build testing for dev workflows
- rel-with-deb-info
- build-testing-on
- coverage-gcc
- coverage-pytest
test:
event-handlers:
- console_direct+
- desktop_notification+
Advanced Workflows with Overlay Images
Creating a Release Container
In your existing Dockerfile
, we will create a new stage called user-overlay
which builds the source code for release and sets up an entrypoint (a script that executes at container startup).
FROM base as user-overlay
ARG USERNAME
ARG USER_WS=/home/${USERNAME}/user_ws
ENV USER_WS=${USER_WS}
# Compile the workspace
WORKDIR $USER_WS
# hadolint ignore=SC1091
RUN --mount=type=cache,target=/home/${USERNAME}/.ccache \
. /opt/overlay_ws/install/setup.sh && \
colcon build
CMD ["/usr/bin/bash"]
Next, create a docker-compose.yaml
file which extends the docker-compose.yaml
file that was installed with MoveIt Pro.
The default location for the installed file is ${HOME}/moveit_pro/docker-compose.yaml
, but feel free to change this for your setup.
version: "3.9"
services:
# Sets common properties for other services. Should not be instantiated directly.
base:
# Extend the installed MoveIt Pro docker compose file.
# Change this to match your environment, if MoveIt Pro was installed to a different location.
extends:
file: ${HOME}/moveit_pro/docker-compose.yaml
service: base
image: moveit-pro-overlay
build:
context: .
target: user-overlay
args:
- USER_UID=${STUDIO_USER_UID:-1000}
- USER_GID=${STUDIO_USER_UID:-1000}
- USERNAME=${STUDIO_USERNAME:-studio-user}
# Set the user workspace folder location.
environment:
- USER_WS=/home/${USERNAME:-studio-user}/user_overlay_ws
Similarly, you can extend all the services from the base image as follows.
This can be directly copied from the docker-compose.yaml
that is installed with MoveIt Pro.
# Additional services
# Starts the MoveIt Pro Agent and the Bridge between the Agent and the Web UI
agent_bridge:
extends: base
privileged: true
# Allow the user to use the host's network video4linux and usb_device devices.
# "c 81:* rmw": This rule specifies that the container has read, write, and mknod access (rmw) to all character devices (c) with a major number of 81 (video4linux).
# "c 189:* rmw": This rule gives the container read, write, and mknod access (rmw) to all character devices (c) with a major number of 189 (usb_device).
device_cgroup_rules:
- "c 81:* rmw"
- "c 189:* rmw"
volumes:
# Allow the user to run graphical programs from within the docker container.
- /tmp/.X11-unix:/tmp/.X11-unix:ro
# Allow access to host hardware e.g. RealSense cameras
- /dev:/dev
deploy:
restart_policy:
condition: any
delay: 2s
command: agent_bridge.app
# Starts the REST API for the Web UI.
rest_api:
extends: base
depends_on:
agent_bridge:
condition: service_healthy
healthcheck:
test: "curl -f http://localhost:3200/objectives"
interval: 5s
timeout: 1m
command: rest_api.app
# Starts the robot drivers.
drivers:
extends: base
privileged: true
# Ensures the drivers container has RT priority
ulimits:
rtprio: 99
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0" # Allow access to the gripper.
command: robot.app
# Starts the web UI frontend.
web_ui:
image: picknikciuser/moveit-studio-frontend:${STUDIO_DOCKER_TAG:-main}
ports:
- "80:80"
network_mode: host
# Starts RViz for visualization.
rviz:
extends: base
profiles:
- rviz
command: bash -c "ros2 launch moveit_studio_agent developer_rviz.launch.py"
# Starts MoveIt Setup Assistant for creating MoveIt configurations.
setup_assistant:
extends: base
profiles:
- setup_assistant
command: bash -c "ros2 launch moveit_setup_assistant setup_assistant.launch.py"
Finally, you can create a .env
file containing the necessary variables to use when launching MoveIt Pro.
For this example, you can include the following contents.
# Robot configuration package to launch
STUDIO_CONFIG_PACKAGE=picknik_ur_mock_hw_config
# MoveIt Pro version tag
# Be careful! Changing this without understanding the consequences may break your installation.
STUDIO_DOCKER_TAG=4.0.0
# Licensing -- enter your MoveIt Pro license below
STUDIO_LICENSE_KEY=
# User name, UID, and GID to use when building the container
# Ensure these settings match your host environment for mounted file permissions.
USERNAME=
STUDIO_USER_UID=
STUDIO_USER_GID=
Now, you should be able to build and launch your MoveIt Pro overlay release image:
docker compose up
You can find a completed version of this example in the moveit_studio_ur_ws repository.
Creating a Dev Container
With the release container workflow from the previous section, every time you change your source code you will need to rebuild the Docker image entirely for the changes to take effect when launching MoveIt Pro. One way to get around this is by making a developer container (or dev container) that mounts the source code and lets you build and run it repeatedly without restarting the container.
As an example, let us extend the base
target in our Dockerfile
with a development target that adds a few extra packages for debugging.
FROM base as user-overlay-dev
ARG USERNAME
ARG USER_WS=/home/${USERNAME}/user_ws
ENV USER_WS=${USER_WS}
# Install any additional packages for development work
# hadolint ignore=DL3008
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install -y --no-install-recommends \
less \
gdb \
nano
CMD ["/usr/bin/bash"]
You can then extend the docker-compose.yaml
file with a new service named dev
as follows:
# Developer specific configuration
dev:
extends: base
build:
target: user-overlay-dev
image: moveit-pro-overlay-dev
stdin_open: true
tty: true
privileged: true
volumes:
# Mount the source code, colcon generated artifacts, and ccache
- ./src/:/home/${USERNAME:-studio-user}/user_ws/src:rw
- ./build/:/home/${USERNAME:-studio-user}/user_ws/build:rw
- ./install/:/home/${USERNAME:-studio-user}/user_ws/install:rw
- ./log/:/home/${USERNAME:-studio-user}/user_ws/log:rw
- ./.ccache/:/home/${USERNAME:-studio-user}/.ccache:rw
- ${HOME}/.ros/log_moveit_pro:/home/${USERNAME:-studio-user}/.ros/log
# Allow access to host hardware e.g. RealSense cameras
- /dev:/dev
command: sleep infinity
# Making a separate profile prevents this service from being built when using `docker compose build`
# and launched when using `docker compose up`.
profiles: ["dev"]
Note that we mount several folders in addition to the src
folder of the workspace.
This ensures that artifacts generated by colcon build
persist between container instances.
Now, you should be able to build and launch your MoveIt Pro overlay dev container:
docker compose build dev
docker compose up dev
Once you have started the dev container, you can enter an interactive Bash session and launch one of the MoveIt Pro launch files directly. For example:
docker compose exec -it dev bash
Once inside the container, you can compile, run tests, or even launch different parts of the MoveIt Pro application.
colcon build
source install/setup.bash
ros2 launch moveit_studio_agent developer_rviz.launch.py
To run MoveIt Pro in its entirety using a dev container, you will need to attach to multiple terminals using docker compose exec -it dev bash
.
In separate terminals, start all the individual backend services.
agent.app
robot.app
studio_bridge.app
rest_api.app
Once these services are all up, you can launch the web app.
docker compose up web_ui
Note
Using Docker containers for development is a common practice. Many IDEs, such as Visual Studio Code and PyCharm, have built-in support for developing with Docker containers. Once you have familiarized yourself with the steps above, we recommend setting up your favorite IDE(s) to help you develop new functionality for MoveIt Pro.