docker-ros automatically builds minimal container images of ROS applications.
Important
This repository is open-sourced and maintained by the Institute for Automotive Engineering (ika) at RWTH Aachen University.
DevOps, Containerization and Orchestration of Software-Defined Vehicles are some of many research topics within our Vehicle Intelligence & Automated Driving domain.
If you would like to learn more about how we can support your advanced driver assistance and automated driving efforts, feel free to reach out to us!
đź“§ [email protected]
We recommend to use docker-ros in combination with our other tools for Docker and ROS.
- docker-ros-ml-images provides machine learning-enabled ROS Docker images 
- docker-run is a CLI tool for simplified interaction with Docker images 
docker-ros provides a generic Dockerfile that can be used to build development and deployment Docker images for arbitrary ROS packages or package stacks. Building such images can easily be automated by integrating docker-ros into CI through the provided GitHub action or GitLab CI template. The development image built by docker-ros contains all required dependencies and the source code of your ROS-based repository. The deployment image only contains dependencies and the compiled binaries created by building the ROS packages in the repository. docker-ros is also able to build multi-arch Docker images for amd64 and arm64 architectures. In addition, slim is integrated for slimming Docker image size of the deployment image by up to 30x (see Slim Deployment Image).
The Dockerfile performs the following steps to build these images:
- All dependency repositories that are defined in a .reposfile anywhere in the repository are cloned using vcstool.
- (optional) Packages blacklisted in a special file blacklisted-packages.txtare removed from the workspace (see Advanced Dependencies).
- (optional) A special script before_dependency_installation.shis executed to perform arbitrary installation commands, if needed (see Advanced Dependencies).
- The ROS dependencies listed in each package's package.xmlare installed by rosdep.
- (optional) Additional apt dependencies from a special file additional-debs.txtare installed, if needed (see Advanced Dependencies).
- (optional) Additional pip requirements from a special file additional-pip-requirements.txtare installed, if needed (see Advanced Dependencies).
- (optional) A special folder additional-files/is copied into the images, if needed (see Advanced Dependencies).
- (optional) A special script custom.shis executed to perform arbitrary installation commands, if needed (see Advanced Dependencies).
- (deployment) All ROS packages are built using colcon(ROS2).
- (deployment) A custom launch command is configured to run on container start.
docker-ros is made for automated execution in GitHub or GitLab CI pipelines. For local execution, see Build images locally.
GitHub
GitHub offers free minutes on GitHub-hosted runners executing GitHub Actions, see here. No further setup is required other than integrating docker-ros into your repository, see Usage.
Note that GitHub is currently only offering Linux runners based on the amd64 architecture. docker-ros can also build multi-arch Docker images solely on the amd64 platform through emulation, but performance can be improved greatly by deploying self-hosted runners for the arm64 platform.
GitLab
[!NOTE]
GitLab offers free minutes on GitLab-hosted runners executing GitLab CI pipelines on gitlab.com, see here. On self-hosted GitLab instances, you can set up self-hosted runners, see here.
Note that GitLab is currently only offering Linux runners based on the amd64 architecture. docker-ros can also build multi-arch Docker images solely on the amd64 platform through emulation, but performance can be improved greatly by deploying self-hosted runners for the arm64 platform.
docker-ros can easily be integrated into any GitHub or GitLab repository containing ROS packages. Example integrations can be found in the following sections. Configuration options can be found here. For local execution, see Build images locally.
GitHub
docker-ros provides a GitHub action that can simply be added to a job via the jobs.<job_id>.steps[*].uses keyword. A quick start for GitHub Actions is found here.
GitLab
docker-ros provides a GitLab CI template that can simply be included in a .gitlab-ci.yml file. A quick start for GitLab CI is found here.
GitHub
on: push
jobs:
  docker-ros:
    runs-on: ubuntu-latest
    steps:
      - uses: ika-rwth-aachen/[email protected]
        with:
          base-image: rwthika/ros2:jazzy
          command: ros2 run my_pkg my_nodeGitLab
include:
  - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/v1.8.1/.gitlab-ci/docker-ros.yml
variables:
  BASE_IMAGE: rwthika/ros2:jazzy
  COMMAND: ros2 run my_pkg my_nodeGitHub
on: push
jobs:
  docker-ros:
    runs-on: ubuntu-latest
    steps:
      - uses: ika-rwth-aachen/[email protected]
        with:
          base-image: rwthika/ros2:jazzy
          command: ros2 run my_pkg my_node
          target: dev,runGitLab
include:
  - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/v1.8.1/.gitlab-ci/docker-ros.yml
variables:
  BASE_IMAGE: rwthika/ros2:jazzy
  COMMAND: ros2 run my_pkg my_node
  TARGET: dev,runGitHub
on: push
jobs:
  docker-ros:
    runs-on: ubuntu-latest
    steps:
      - uses: ika-rwth-aachen/[email protected]
        with:
          base-image: rwthika/ros2:jazzy
          command: ros2 run my_pkg my_node
          target: dev,run
          platform: amd64,arm64GitLab
include:
  - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/v1.8.1/.gitlab-ci/docker-ros.yml
variables:
  BASE_IMAGE: rwthika/ros2:jazzy
  COMMAND: ros2 run my_pkg my_node
  TARGET: dev,run
  PLATFORM: amd64,arm64GitHub
on: push
jobs:
  docker-ros:
    runs-on: ubuntu-latest
    steps:
      - uses: ika-rwth-aachen/[email protected]
        with:
          base-image: rwthika/ros2:jazzy
          command: ros2 run my_pkg my_node
          enable-industrial-ci: 'true'GitLab
include:
  - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/v1.8.1/.gitlab-ci/docker-ros.yml
variables:
  BASE_IMAGE: rwthika/ros2:jazzy
  COMMAND: ros2 run my_pkg my_node
  ENABLE_INDUSTRIAL_CI: 'true'GitHub
on: push
jobs:
  docker-ros:
    strategy:
      matrix:
        target: [dev, run]
        platform: [amd64, arm64]
    runs-on: [self-hosted, "${{ matrix.platform }}"]
    steps:
      - uses: ika-rwth-aachen/[email protected]
        with:
          base-image: rwthika/ros2:jazzy
          command: ros2 run my_pkg my_node
          target: ${{ matrix.target }}
          platform: ${{ matrix.platform }}
          enable-singlearch-push: true
      # TODO: manifestGitLab
# TODOdocker-ros can build Docker images locally by executing the build.sh script.
- Clone docker-ros as a Git submodule to docker/docker-rosin your repository.# ros-repository/ mkdir -p docker git submodule add https://github.com/ika-rwth-aachen/docker-ros.git docker/docker-ros
- Configure the build using the same environment variables as used for GitLab CI and run build.sh, e.g.:# ros-repository/ BASE_IMAGE="rwthika/ros2:jazzy" \ COMMAND="ros2 run my_pkg my_node" \ IMAGE="my-image:latest" \ ./docker/docker-ros/scripts/build.sh [!NOTE] 
 You can alternatively store your environment variable configuration in a.envfile:# .env BASE_IMAGE="rwthika/ros2:jazzy" COMMAND="ros2 run my_pkg my_node" IMAGE="my-image:latest" 
In order to keep things organized, we recommend to place all docker-ros related files in a docker folder on top repository level.
Most of the steps listed in About and below can be toggled between recursive and non-recursive mode, see Configuration Variables. This usually means that not only special files on the top-level are considered (e.g., docker/additional-requirements.txt), but also files with the same name (e.g., additional-requirements.txt) that are found anywhere in the workspace, even after cloning the upstream repositories in step 1.
If your ROS-based repository (or any of your repository's upstream dependencies, see .repos) contains ROS packages that should neither be built nor be used for determining dependencies, you can blacklist those in a special blacklisted-packages.txt file.
Create a file blacklisted-packages.txt in your docker folder (or configure a different BLACKLISTED_PACKAGES_FILE) and list any ROS package name to blacklist.
If your ROS-based repository requires system dependencies that cannot be installed by specifying their rosdep keys in a package.xml, you can use a special additional-debs.txt file.
Create a file additional-debs.txt in your docker folder (or configure a different ADDITIONAL_DEBS_FILE) and list any other dependencies that need to be installed via apt.
If your ROS-based repository requires Python dependencies that cannot be installed by specifying their rosdep keys in a package.xml, you can use a special additional-pip-requirements.txt file.
Create a file additional-pip-requirements.txt in your docker folder (or configure a different ADDITIONAL_PIP_FILE) and list any other Python dependencies that need to be installed via pip.
If your ROS-based repository requires to execute any other installation or pre-/post-installation steps, you can specify multiple custom scripts that are executed during the image building process. See the configuration variable documentation for the following variables.
- BEFORE_DEPENDENCY_IDENTIFICATION_SCRIPT
- BEFORE_DEPENDENCY_INSTALLATION_SCRIPT
- AFTER_DEPENDENCY_INSTALLATION_SCRIPT
Create those scripts in your docker folder (or configure different filepaths via the specified environment variables).
If you need to have additional files present in the deployment image, you can use a special additional-files folder. The folder contents will be copied into the container before the custom installation script custom.sh is executed.
Create a folder additional-files in your docker folder (or configure a different ADDITIONAL_FILES_DIR) and place any files or directories in it. The contents will be copied to /docker-ros/additional-files in the image.
Containers of the provided images start with root user by default. If the two environment variables DOCKER_UID and DOCKER_GID are passed, a new user with the corresponding UID/GID is created on the fly. Most importantly, this features allows to mount and edit files of the host user in the container without having to deal with permission issues.
docker run --rm -it -e DOCKER_UID=$(id -u) -e DOCKER_GID=$(id -g) -e DOCKER_USER=$(id -un) rwthika/ros:latestThe password of the custom user is set to its username (dockeruser:dockeruser by default).
docker-ros integrates the slim toolkit for minifying container images. slim is enabled by default and will, in addition to the run deployment image, produce an additional :latest-slim-tagged minified image. Note that slim removes every single thing not needed for executing the default launch command. To balance image size and out-of-the-box functionality, the /opt/ros and /docker-ros/ws/install directories are preserved by default. The slimming process can be controlled via the SLIM_BUILD_ARGS configuration variable.
Note
GitHub Action input | GitLab CI environment variable
- additional-debs-file|- ADDITIONAL_DEBS_FILE
 Relative filepath to file containing additional apt deb packages to install
 default:- docker/additional-debs.txt
- additional-files-dir|- ADDITIONAL_FILES_DIR
 Relative path to directory containing additional files to copy into image
 default:- docker/additional-files
- additional-pip-file|- ADDITIONAL_PIP_FILE
 Relative filepath to file containing additional pip packages to install
 default:- docker/additional-pip-requirements.txt
- after-dependency-installation-script|- AFTER_DEPENDENCY_INSTALLATION_SCRIPT
 Relative filepath to script containing commands to run after dependency installation
 default:- docker/custom.sh
- base-image|- BASE_IMAGE
 Base image- name:tag
 required
- before-dependency-identification-script|- BEFORE_DEPENDENCY_IDENTIFICATION_SCRIPT
 Relative filepath to script containing commands to run before dependency identification
 default:- docker/before_dependency_identification.sh
- before-dependency-installation-script|- BEFORE_DEPENDENCY_INSTALLATION_SCRIPT
 Relative filepath to script containing commands to run before dependency installation
 default:- docker/before_dependency_installation.sh
- blacklisted-packages-file|- BLACKLISTED_PACKAGES_FILE
 Relative filepath to file containing blacklisted packages
 default:- docker/blacklisted-packages.txt
- build-context|- BUILD_CONTEXT
 Build context of Docker build process
 default:- ${{ github.workspace }}|- .
- command|- COMMAND
 Launch command of run image
 required if- target=run
- cmake-args|- CMAKE_ARGS
 CMake arguments to pass to- colcon build
 default:- "-DCMAKE_BUILD_TYPE=Release"
- dev-image-name|- DEV_IMAGE_NAME
 Image name of dev image
 default:- <IMAGE_NAME>
- dev-image-tag|- DEV_IMAGE_TAG
 Image tag of dev image
 default:- <IMAGE_TAG>-dev
- disable-ros-installation|- DISABLE_ROS_INSTALLATION
 Disable automatic installation of- ros-$ROS_DISTRO-ros-corepackage
 e.g., if ROS is already installed in- base-imageand package is not available for the OS
 default:- false
- -|- DOCKER_ROS_GIT_REF
 Git ref of docker-ros to run in CI
 default:- main
- enable-checkout|- -
 Enable checkout action to (re-)download your repository prior to running the pipeline
 default:- true
- enable-checkout-submodules|- -
 Enable submodules for the checkout action (- false|- true|- recursive)
 default:- recursive
- enable-checkout-lfs|- -
 Enable Git LFS support for the checkout action
 default:- true
- enable-industrial-ci|- ENABLE_INDUSTRIAL_CI
 Enable industrial_ci
 default:- false
- enable-push-as-latest|- ENABLE_PUSH_AS_LATEST
 Push images with tag- latest/- latest-devin addition to the configured image names
 default:- false
- enable-singlearch-push|- ENABLE_SINGLEARCH_PUSH
 Enable push of single arch images with- -amd64/- -arm64postfix
 default:- false
- enable-recursive-additional-debs|- ENABLE_RECURSIVE_ADDITIONAL_DEBS
 Enable recursive discovery of files named- additional-debs-file
 default:- false
- enable-recursive-additional-pip|- ENABLE_RECURSIVE_ADDITIONAL_PIP
 Enable recursive discovery of files named- additional-pip-file
 default:- false
- enable-recursive-after-dependency-installation-script|- ENABLE_RECURSIVE_AFTER_DEPENDENCY_INSTALLATION_SCRIPT
 Enable recursive discovery of files named- after-dependency-installation-script
 default:- false
- enable-recursive-before-dependency-installation-script|- ENABLE_RECURSIVE_BEFORE_DEPENDENCY_INSTALLATION_SCRIPT
 Enable recursive discovery of files named- before-dependency-installation-script
 default:- false
- enable-recursive-blacklisted-packages|- ENABLE_RECURSIVE_BLACKLISTED_PACKAGES
 Enable recursive discovery of files named- blacklisted-packages-file
 default:- false
- enable-recursive-vcs-import|- ENABLE_RECURSIVE_VCS_IMPORT
 Enable recursive discovery of files named- *.repos
 default:- true
- enable-slim|- ENABLE_SLIM
 Enable an extra slimmed run image via slim (only if- runstage is targeted)
 default:- true
- git-https-password|- GIT_HTTPS_PASSWORD
 Password for cloning private Git repositories via HTTPS
 default:- ${{ github.token }}|- $CI_JOB_TOKEN
- git-https-server|- GIT_HTTPS_SERVER
 Server URL (without protocol) for cloning private Git repositories via HTTPS
 default:- github.com|- $CI_SERVER_HOST:$CI_SERVER_PORT
- git-https-user|- GIT_HTTPS_USER
 Username for cloning private Git repositories via HTTPS
 default:- ${{ github.actor }}|- gitlab-ci-token
- git-ssh-known-host-keys|- GIT_SSH_KNOWN_HOST_KEYS
 Known SSH host keys for cloning private Git repositories via SSH (may be obtained using- ssh-keyscan)
- git-ssh-private-key|- GIT_SSH_PRIVATE_KEY
 SSH private key for cloning private Git repositories via SSH
- image-name|- IMAGE_NAME
 Image name of run image
 default:- ghcr.io/${{ github.repository }}|- $CI_REGISTRY_IMAGE
- image-tag|- IMAGE_TAG
 Image tag of run image default:- latest
- platform|- PLATFORM
 Target platform architecture (comma-separated list)
 default: runner architecture |- amd64supported values:- amd64,- arm64
- registry|- REGISTRY
 Docker registry to push images to
 default:- ghcr.io|- $CI_REGISTRY
- registry-password|- REGISTRY_PASSWORD
 Docker registry password
 default:- ${{ github.token }}|- $CI_REGISTRY_PASSWORD
- registry-user|- REGISTRY_USER
 Docker registry username
 default:- ${{ github.actor }}|- $CI_REGISTRY_USER
- rmw-implementation|- RMW_IMPLEMENTATION
 ROS 2 middleware implementation
 default:- rmw_fastrtps_cpp
 supported values:- rmw_zenoh_cpp,- rmw_fastrtps_cpp,- rmw_cyclonedds_cpp,- rmw_gurumdds_cpp, ...
- ros-distro|- ROS_DISTRO
 ROS Distro
 required if ROS is not installed in- base-image
 supported values:- rolling, ...,- noetic, ...
- slim-build-args|- SLIM_BUILD_ARGS
 Arguments to- slim build(except for- --targetand- --tag)
 default:- --sensor-ipc-mode proxy --continue-after=10 --show-clogs --http-probe=false --include-path /opt/ros --include-path /docker-ros/ws/install
- slim-image-name|- SLIM_IMAGE_NAME
 Image name of slim run image
 default:- <IMAGE_NAME>
- slim-image-tag|- SLIM_IMAGE_TAG
 Image tag of slim run image
 default:- <IMAGE_TAG>-slim
- target|- TARGET
 Target stage of Dockerfile (comma-separated list)
 default:- runsupported values:- dev,- run
- vcs-import-file|- VCS_IMPORT_FILE
 Relative filepath to file containing additional repos to install via vcstools (only relevant if- enable-recursive-vcs-import=false)
 default:- .repos
