Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ docker
!docker/etc
!docker/scripts
!docker/tools
!docker/rhel-extra-deps.repos

# Ignore a part of files under src
src/**/.*
Expand Down
479 changes: 479 additions & 0 deletions docker/Dockerfile.rhel

Large diffs are not rendered by default.

223 changes: 223 additions & 0 deletions docker/README-rhel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
# Autoware on RHEL 9 (AlmaLinux 9): containerized build

This document describes how to build Autoware container images on AlmaLinux 9 (RHEL 9 compatible) using `docker/Dockerfile.rhel`.

## Key differences from Ubuntu build

| Aspect | Ubuntu (`Dockerfile`) | RHEL (`Dockerfile.rhel`) |
| ------------------ | ------------------------------------ | ---------------------------------------------------- |
| Base image | Pre-built `$AUTOWARE_BASE_IMAGE` | `almalinux:9` (from scratch) |
| Package manager | apt-get | dnf |
| ROS 2 installation | Inherited from base image | RHEL 9 binary tarball downloaded in `base` stage |
| System setup | `setup-dev-env.sh` (Ansible) | Direct `dnf install` |
| CUDA | Supported (devel-cuda / cuda stages) | Not supported (COLCON_IGNORE) |
| Extra ROS packages | Inherited from base image | `rhel-extra-deps.repos` (37 repos built from source) |

## Prerequisites

- Docker with BuildKit enabled
- Autoware source cloned with `vcs import`:

```bash
git clone https://github.com/autowarefoundation/autoware.git
cd autoware
mkdir src
vcs import src < autoware.repos
```

## Quick start

### Build development image (all packages + build tools)

```bash
cd /path/to/autoware
docker build \
--progress=plain \
--build-arg ROS_DISTRO=jazzy \
--target universe-devel \
-t autoware-rhel-universe-devel:latest \
-f docker/Dockerfile.rhel \
.
```

### Build runtime image (binaries only, no build tools)

```bash
docker build \
--progress=plain \
--build-arg ROS_DISTRO=jazzy \
--target universe \
-t autoware-rhel-universe:latest \
-f docker/Dockerfile.rhel \
.
```

### Run the container

```bash
# Runtime image
docker run -it --rm autoware-rhel-universe:latest

# Development image with volume mount
docker run -it --rm \
-v $PWD/src/universe/autoware_universe/planning/autoware_path_optimizer:/autoware/src/autoware_path_optimizer \
autoware-rhel-universe-devel:latest

# Runtime image with UID/GID remapping
docker run -it --rm \
-e LOCAL_UID=$(id -u) -e LOCAL_USER=$(whoami) \
-e LOCAL_GID=$(id -g) -e LOCAL_GROUP=$(id -gn) \
-v /path/to/autoware_data:/autoware_data \
autoware-rhel-universe:latest
```

## Build targets

| Target | Type | Size | Description |
| ----------------------- | ----------- | -------- | ----------------------------------------------------------------- |
| `universe-devel` | Development | ~13.7 GB | All build tools, headers, source, and compiled artifacts |
| `universe` | Runtime | ~7 GB | Runtime libraries and binaries only |
| `core-devel` | Development | — | Core packages only (autoware_msgs, autoware_utils, autoware_core) |
| `core` | Runtime | — | Runtime image for core packages only |
| `universe-common-devel` | Development | — | Core + common/external/middleware packages |

Specify the target with `--target`:

```bash
docker build --target core-devel -t autoware-rhel-core-devel -f docker/Dockerfile.rhel .
```

## Multi-stage Dockerfile structure

```
[base] almalinux:9 + ROS 2 Jazzy binary + dnf deps
├─[source-deps] clone rhel-extra-deps.repos (37 ROS packages)
│ │
│ └─[rosdep-depend] resolve system deps for Autoware + extra deps
│ ├─ /rosdep-all-depend-packages.txt (build + runtime)
│ └─ /rosdep-exec-depend-packages.txt (runtime only)
├─[core-common-devel] autoware_msgs, autoware_utils + deps_src
│ │
│ └─[core-devel] autoware_core packages
│ │
│ └─[universe-common-devel] external, common, middleware, launcher
│ │
│ ├─[universe-sensing-perception-devel] ─┐
│ ├─[universe-localization-mapping-devel] │ BuildKit runs
│ ├─[universe-planning-control-devel] │ these 6 stages
│ ├─[universe-vehicle-system-devel] │ in parallel
│ ├─[universe-visualization-devel] │
│ └─[universe-api-devel] ─┘
│ │
│ └─[universe-devel] COPY --from all 6 + strip + final build
└─[runtime-base] almalinux:9 + runtime libs only (no build tools)
├─[core] COPY from core-devel + exec rosdep deps
└─[universe] COPY from universe-devel + exec rosdep deps
```

### Stage descriptions

#### `base`

AlmaLinux 9 with EPEL and CRB repositories enabled. Installs system development libraries via `dnf`, downloads the [ROS 2 Jazzy RHEL 9 binary](https://github.com/ros2/ros2/releases) to `/opt/ros/jazzy/`, and applies RHEL-specific fixes (yaml-cpp CMake alias, magic_enum and png++ header-only libraries).

#### `source-deps`

Clones 37 ROS 2 packages from `rhel-extra-deps.repos` that are not included in the RHEL binary (which is ros-base equivalent, 371 packages). Selectively applies COLCON_IGNORE to sub-packages that cannot build on RHEL (e.g., rviz plugins, spacenav, wiimote).

#### `rosdep-depend`

Resolves rosdep keys to RHEL 9 system package names using `resolve_rosdep_keys_rhel.sh`. Generates two package lists: all dependencies (for devel stages) and exec-only dependencies (for runtime stages).

#### `core-common-devel`

Installs rosdep system packages via `dnf`. Copies extra dependency sources to `/autoware/deps_src/`. Applies runtime patches (M_PIf, CUDA COLCON_IGNORE, agnocast dedup). Builds core framework packages (autoware_msgs, autoware_utils, and all deps_src) to `/opt/autoware/`.

#### `core-devel`

Builds `autoware_core` packages on top of `core-common-devel`.

#### `universe-common-devel`

Builds common, external, middleware, and launcher packages.

#### `universe-{component}-devel`

Six parallel stages that each build a specific subsystem: sensing/perception, localization/mapping, planning/control, vehicle/system, visualization, and API.

#### `universe-devel`

Aggregates all six parallel stages via `COPY --from`, strips debug symbols from binaries, and runs a final build pass for remaining packages (evaluator, simulator, sensor_component).

#### `runtime-base`

Minimal AlmaLinux 9 image with only runtime libraries (no compilers, no `-devel` headers). Copies `/opt/ros/` from the `base` stage. Installs gosu for UID/GID remapping and Python runtime dependencies for `ros2` CLI.

#### `core` / `universe`

Runtime images that copy `/opt/autoware/` from corresponding devel stages and install exec-only rosdep dependencies. Broken ament_index entries (from packages that failed to build) are automatically cleaned up.

## RHEL-specific adaptations

### ROS 2 Jazzy RHEL binary

The official RHEL 9 binary provides ros-base equivalent (371 packages). Packages like `diagnostic_updater`, `geographic_msgs`, `pcl_ros`, `lanelet2_core`, `grid_map`, `filters`, etc. are not included and must be built from source via `rhel-extra-deps.repos`.

### Build script patches (`build_and_clean_rhel.sh`)

The build script applies runtime patches before each colcon build to handle RHEL 9 incompatibilities:

| Patch | Reason |
| --------------------------------------------- | ---------------------------------------------------------- |
| `M_PIf` / `M_PI_2f` / `M_PI_4f` guards | GCC 11 on RHEL 9 does not define C23 math float constants |
| CUDA packages COLCON_IGNORE | 30 CUDA-dependent packages excluded (no CUDA toolkit) |
| `tl/expected.hpp` warning suppression | Deprecation `#warning` becomes error with `-Werror=cpp` |
| Boost 1.75 `strategies/cartesian.hpp` include | `correct.hpp` and `is_valid.hpp` missing strategy includes |
| `boost::geometry::is_valid()` bypass | Fails on custom Eigen-based Point2d with Boost < 1.77 |

The build uses a **three-pass retry strategy**: if packages fail, their `build/` directories are deleted and colcon retries on the next pass. This handles dependency ordering issues.

### Rosdep resolution (`resolve_rosdep_keys_rhel.sh`)

Uses `--os=rhel:9` to resolve against RHEL packages instead of Ubuntu defaults. Filters out `ros-jazzy-*` package names (no RPM repository for ROS on RHEL).

### yaml-cpp CMake alias

RHEL 9 ships yaml-cpp 0.6.3 which exports the CMake target `yaml-cpp`, but ROS 2 expects `yaml-cpp::yaml-cpp`. The `base` stage appends an alias to the CMake config file.

## Known limitations

- **No CUDA support**: All TensorRT/CUDA packages are excluded via COLCON_IGNORE. Perception nodes that require GPU inference will not be available.
- **Boost 1.75 constraints**: `boost::geometry::is_valid()` is bypassed with a simpler polygon size check for custom Point types. This may affect geometric validation accuracy in edge cases.
- **Build failures**: A small number of packages may fail to build (e.g., `autoware_control_evaluator` due to missing `boundary_departure_checker` header). These are automatically excluded from runtime images.
- **No setup-dev-env.sh**: The Ubuntu Ansible-based environment setup is replaced with direct `dnf install`. Some development tools available in the Ubuntu image may be missing.

## UID/GID remapping

The runtime images use `ros_entrypoint.sh` with gosu for UID/GID remapping. Set the following environment variables to run as a non-root user:

```bash
docker run -it --rm \
-e LOCAL_UID=1000 -e LOCAL_USER=developer \
-e LOCAL_GID=1000 -e LOCAL_GROUP=developers \
-v /path/to/autoware_data:/autoware_data \
autoware-rhel-universe:latest
```

If these variables are not set, the container runs as root.

## Files reference

| File | Description |
| -------------------------------------------- | --------------------------------------------------------------- |
| `docker/Dockerfile.rhel` | Multi-stage Dockerfile (16 stages) for RHEL 9 build |
| `docker/rhel-extra-deps.repos` | VCS manifest of 37 ROS packages not in RHEL binary |
| `docker/scripts/build_and_clean_rhel.sh` | Colcon build orchestration with RHEL patches and 3-pass retry |
| `docker/scripts/resolve_rosdep_keys_rhel.sh` | Rosdep resolution with `--os=rhel:9` and `ros-*` filtering |
| `docker/scripts/cleanup_dnf.sh` | DNF cache cleanup |
| `docker/etc/ros_entrypoint.sh` | Container entrypoint with UID/GID remapping via gosu |
| `.dockerignore` | Build context filter (includes `!docker/rhel-extra-deps.repos`) |
154 changes: 154 additions & 0 deletions docker/rhel-extra-deps.repos
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
repositories:
geographic_info:
type: git
url: https://github.com/ros-geographic-info/geographic_info.git
version: ros2
perception_pcl:
type: git
url: https://github.com/ros-perception/perception_pcl.git
version: jazzy
pcl_msgs:
type: git
url: https://github.com/ros-perception/pcl_msgs.git
version: ros2
vision_opencv:
type: git
url: https://github.com/ros-perception/vision_opencv.git
version: rolling
image_common:
type: git
url: https://github.com/ros-perception/image_common.git
version: jazzy
diagnostics:
type: git
url: https://github.com/ros/diagnostics.git
version: ros2
bond_core:
type: git
url: https://github.com/ros/bond_core.git
version: ros2
laser_geometry:
type: git
url: https://github.com/ros-perception/laser_geometry.git
version: ros2
grid_map:
type: git
url: https://github.com/ANYbotics/grid_map.git
version: jazzy
Lanelet2:
type: git
url: https://github.com/fzi-forschungszentrum-informatik/Lanelet2.git
version: master
mrt_cmake_modules:
type: git
url: https://github.com/KIT-MRT/mrt_cmake_modules.git
version: master
osqp_vendor:
type: git
url: https://github.com/tier4/osqp_vendor.git
version: main
topic_tools:
type: git
url: https://github.com/ros-tooling/topic_tools.git
version: main
angles:
type: git
url: https://github.com/ros/angles.git
version: ros2
filters:
type: git
url: https://github.com/ros/filters.git
version: ros2
octomap_msgs:
type: git
url: https://github.com/OctoMap/octomap_msgs.git
version: ros2
radar_msgs:
type: git
url: https://github.com/ros-perception/radar_msgs.git
version: ros2
vision_msgs:
type: git
url: https://github.com/ros-perception/vision_msgs.git
version: ros2
ros_canopen:
type: git
url: https://github.com/ros-industrial/ros_canopen.git
version: dashing-devel
foxglove_sdk:
type: git
url: https://github.com/foxglove/foxglove-sdk.git
version: main
udp_msgs:
type: git
url: https://github.com/flynneva/udp_msgs.git
version: main
xacro:
type: git
url: https://github.com/ros/xacro.git
version: ros2
joystick_drivers:
type: git
url: https://github.com/ros-drivers/joystick_drivers.git
version: ros2
tf_transformations:
type: git
url: https://github.com/DLu/tf_transformations.git
version: main
cpp_polyfills:
type: git
url: https://github.com/PickNikRobotics/cpp_polyfills.git
version: main
RSL:
type: git
url: https://github.com/PickNikRobotics/RSL.git
version: main
generate_parameter_library:
type: git
url: https://github.com/PickNikRobotics/generate_parameter_library.git
version: humble
rviz_2d_overlay_plugins:
type: git
url: https://github.com/teamspatzenhirn/rviz_2d_overlay_plugins.git
version: main
ublox:
type: git
url: https://github.com/KumarRobotics/ublox.git
version: ros2
rtcm_msgs:
type: git
url: https://github.com/tilk/rtcm_msgs.git
version: master
nmea_msgs:
type: git
url: https://github.com/ros-drivers/nmea_msgs.git
version: ros2
velodyne:
type: git
url: https://github.com/ros-drivers/velodyne.git
version: jazzy-devel
ackermann_msgs:
type: git
url: https://github.com/ros-drivers/ackermann_msgs.git
version: ros2
nav2_msgs:
type: git
url: https://github.com/ros-navigation/navigation2.git
version: jazzy
point_cloud_transport:
type: git
url: https://github.com/ros-perception/point_cloud_transport.git
version: jazzy
proxsuite:
type: git
url: https://github.com/Simple-Robotics/proxsuite.git
version: devel
point_cloud_msg_wrapper:
type: git
url: https://gitlab.com/ApexAI/point_cloud_msg_wrapper.git
version: rolling
behaviortree_cpp:
type: git
url: https://github.com/BehaviorTree/BehaviorTree.CPP.git
version: v3.8
# Cache-bust: 1775602888
Loading
Loading