Skip to content

Migrate Template Workspace to use the AOC Container Base Standard#16

Open
cooperj wants to merge 8 commits intomainfrom
aoc_container_base
Open

Migrate Template Workspace to use the AOC Container Base Standard#16
cooperj wants to merge 8 commits intomainfrom
aoc_container_base

Conversation

@cooperj
Copy link
Copy Markdown
Member

@cooperj cooperj commented Mar 31, 2026

This pull request overhauls the devcontainer and development environment setup for the ROS 2 workspace, making it more flexible and robust for both CPU-only and GPU-accelerated development.

The changes introduce functionality from aoc_container_base, which is a modular Docker Compose based configuration supporting CPU, generic GPU, and NVIDIA GPU profiles. This streamlines the Dockerfile, and reduces the need for CUDA to be enabled inside of this container.

Key changes

Devcontainer and Docker Compose Refactor:

  • Replaces the previous monolithic .devcontainer/Dockerfile and setup with a new multi-stage Dockerfile and modular Docker Compose files (compose.yaml, compose.gpu.yaml, compose.nvidia.yaml). This enables easy selection between CPU-only, generic GPU, and NVIDIA GPU development environments. (.devcontainer/Dockerfile, .devcontainer/compose.yaml, .devcontainer/compose.gpu.yaml, .devcontainer/compose.nvidia.yaml) [1] [2] [3] [4]
  • Removes the legacy post-create script and simplifies dependency installation and workspace build steps directly into the Dockerfile. (.devcontainer/post-create.sh)

Devcontainer Profile Selection:

  • Introduces separate devcontainer.json profiles for CPU-only, generic GPU, and NVIDIA GPU setups, allowing users to easily choose the appropriate environment for their hardware. (.devcontainer/devcontainer.json, .devcontainer/gpu/devcontainer.json, .devcontainer/nvidia/devcontainer.json) [1] [2] [3]

Documentation Updates:

  • Updates README.md to reflect the new workspace structure, explain the different devcontainer profiles, and provide clear guidance on when to use each one. (README.md)
  • Adds a brief README to the src/ directory to clarify its purpose. (src/README.md)

CI Workflow Adjustments:

  • Disabled All Workflows by default, ensuring that end users of this template have full control of their CI pipeline.

  • Renames and updates the GitHub Actions workflow to focus on ROS 2 distributions only, adding support for the latest ROS 2 releases (e.g., Jazzy). (.github/workflows/ros-ci.yml.github/workflows/ros-ci.yml.off) [1] [2].

    • This is done to remove unneeded configuration from ROS 1 Noetic, which is now EOL.

These changes modernize the development environment, making it easier and lighter to work with ROS 2 across a variety of hardware setups and improving the onboarding and development experience.

Next Steps

@cooperj cooperj requested a review from Copilot March 31, 2026 10:55
@cooperj cooperj self-assigned this Mar 31, 2026
@cooperj cooperj added the enhancement New feature or request label Mar 31, 2026
@cooperj cooperj changed the title Migrate to Template Workspace to use the AOC Container Base Standard Migrate Template Workspace to use the AOC Container Base Standard Mar 31, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the ROS 2 template’s development environment to a modular Docker Compose + multi-stage Dockerfile approach (aligned with aoc_container_base), adds CPU/GPU/NVIDIA devcontainer profiles, updates docs, and disables CI workflows by default via .off workflow files.

Changes:

  • Refactors devcontainer setup to Docker Compose with separate CPU / generic GPU / NVIDIA GPU profiles.
  • Simplifies the Dockerfile and removes the legacy post-create script in favor of build/install steps during image build.
  • Updates template documentation and renames/disables CI workflows by default.

Reviewed changes

Copilot reviewed 11 out of 14 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
.devcontainer/Dockerfile Replaces prior multi-stage dependency build with a simpler devcontainer + final stages.
.devcontainer/devcontainer.json Switches default profile to Compose-based CPU-only service configuration.
.devcontainer/gpu/devcontainer.json Adds generic GPU profile using compose overrides.
.devcontainer/nvidia/devcontainer.json Adds NVIDIA GPU profile layering GPU + NVIDIA overrides.
.devcontainer/compose.yaml Introduces develop + vnc services and shared volumes/networks for the workspace.
.devcontainer/compose.gpu.yaml Adds /dev/dri device passthrough overrides.
.devcontainer/compose.nvidia.yaml Adds NVIDIA GPU reservations overrides.
.devcontainer/post-create.sh Removed legacy post-create provisioning script.
README.md Updates onboarding instructions and documents devcontainer profile selection.
src/README.md Adds a short explanation of what belongs in src/.
.github/workflows/ros-ci.yml.off Disables ROS CI by default and updates ROS distro matrix.
.github/workflows/dev-container.yml.off Adds disabled-by-default devcontainer CI workflow.
.github/workflows/build-docker.yml.off Adds disabled-by-default Docker build/publish workflow.
Comments suppressed due to low confidence (1)

.github/workflows/ros-ci.yml.off:11

  • This workflow still references actions/checkout@v6 later in the file, which is not a known released major version (and differs from actions/checkout@v3 used elsewhere in the repo). Update it to an existing major (e.g., v4) so the workflow runs when users re-enable it.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

WORKDIR /workspace

ENV ROS2_WS=/workspace
RUN rosdep update --rosdistro ${ROS_DISTRO} &&\
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rosdep update is executed without ensuring rosdep is installed and initialized (rosdep init). This is a regression from the previous Dockerfile and will break builds on base images that don’t preconfigure rosdep (e.g., official ros:* images). Install python3-rosdep (if not guaranteed by the base) and run rosdep init (idempotently) before rosdep update.

Suggested change
RUN rosdep update --rosdistro ${ROS_DISTRO} &&\
RUN apt-get update && \
apt-get install -y --no-install-recommends python3-rosdep && \
rm -rf /var/lib/apt/lists/* && \
(rosdep init || echo "rosdep already initialized") && \
rosdep update --rosdistro ${ROS_DISTRO} && \

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is an issue as the upstream aoc container has rosdep. All I seem to be doing is running a rosdep update there.


RUN /bin/bash -lc "source /opt/ros/${ROS_DISTRO}/setup.bash && colcon build"

CMD ["/bin/bash", "-lc", "source /workspace/install/setup.bash && exec ros2 launch example example.launch.py"]
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image CMD launches ros2 launch example example.launch.py, but the repository currently has no packages under src/ (only src/README.md). This container will exit/fail by default. Consider making the default command an interactive shell, or include an example package/launch file in the template so the command is valid.

Suggested change
CMD ["/bin/bash", "-lc", "source /workspace/install/setup.bash && exec ros2 launch example example.launch.py"]
CMD ["/bin/bash"]

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repository is intended to be a template showing developers how to implement the workflow.

I am using the example package and example.launch.py as a clear example for illustrative purposes only. This will never be hit by the devcontainer target which is what is being used.

The final target is for creating a container that we can take and put onto a robot.

Comment on lines +11 to +14
"vnc:5801"
],
"portsAttributes": {
"vnc:5801": {
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forwardPorts/portsAttributes entries use "vnc:5801", but devcontainer port forwarding expects a port number (optionally with protocol), not a service:port reference. As written, VS Code won’t forward the noVNC port. Use 5801 (and matching portsAttributes key) and/or publish the VNC container’s port via Compose so it’s reachable from the host.

Suggested change
"vnc:5801"
],
"portsAttributes": {
"vnc:5801": {
5801
],
"portsAttributes": {
"5801": {

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +14
"vnc:5801"
],
"portsAttributes": {
"vnc:5801": {
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forwardPorts/portsAttributes entries use "vnc:5801", but devcontainer port forwarding expects a port number (optionally with protocol), not a service:port reference. As written, VS Code won’t forward the noVNC port. Use 5801 (and matching portsAttributes key) and/or publish the VNC container’s port via Compose so it’s reachable from the host.

Suggested change
"vnc:5801"
],
"portsAttributes": {
"vnc:5801": {
5801
],
"portsAttributes": {
"5801": {

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a bad suggestion.

Comment on lines +12 to +15
"vnc:5801"
],
"portsAttributes": {
"vnc:5801": {
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forwardPorts/portsAttributes entries use "vnc:5801", but devcontainer port forwarding expects a port number (optionally with protocol), not a service:port reference. As written, VS Code won’t forward the noVNC port. Use 5801 (and matching portsAttributes key) and/or publish the VNC container’s port via Compose so it’s reachable from the host.

Suggested change
"vnc:5801"
],
"portsAttributes": {
"vnc:5801": {
"5801"
],
"portsAttributes": {
"5801": {

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +12
services:
vnc:
image: lcas.lincoln.ac.uk/vnc:staging
volumes:
- x11:/tmp/.X11-unix
networks:
- ros_net
environment:
- VNC_WALLPAPER=gir
stdin_open: true
tty: true
ipc: shareable
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The vnc service isn’t publishing any ports (e.g., 5801), but the README/devcontainer config instructs users to connect via noVNC. Since the devcontainer attaches to the develop service, VS Code can’t directly forward ports from the separate vnc service without host publishing. Expose the required noVNC port(s) on vnc (and document them), or run noVNC in the develop container instead.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is being handled by the devcontainer configuration, I think this is a non issue.

@@ -0,0 +1,13 @@
# GPU override — merge on top of compose.yml when any GPU is available.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment says “merge on top of compose.yml” but the repository uses compose.yaml (and the usage example references compose.yaml). Update the comment to match the actual filename to avoid confusion.

Suggested change
# GPU override — merge on top of compose.yml when any GPU is available.
# GPU override — merge on top of compose.yaml when any GPU is available.

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +17
3. You will be asked to select which version you want to run, use the instructions below to determine which version you need.
4. The devcontainer will install all workspace dependencies and build the workspace automatically.
5. Open the ports section to see which port noVNC is listening on.

| Version | When |
| ------- | ---- |
| Default (CPU-safe) | Recommended first choice. Uses no GPU passthrough and works across laptops, VMs, macOS, and Windows hosts. |
| Generic GPU (`/dev/dri`) | Use when your host exposes `/dev/dri` and you want hardware acceleration without NVIDIA runtime requirements. |
| NVIDIA GPU | Use when you have an NVIDIA GPU and [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#setting-up-nvidia-container-toolkit) installed. This profile layers generic GPU and NVIDIA-specific overrides. |
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This README instructs users to “Open the ports section to see which port noVNC is listening on,” but the current devcontainer configuration uses forwardPorts: ["vnc:5801"] (not a valid port-forward entry) and the Compose file doesn’t publish the VNC port. Update the README to reflect the actual connection method/port mapping once the devcontainer/Compose configuration is corrected.

Copilot uses AI. Check for mistakes.

- Add ROS2 packages to the `src/` folder using `ros2 pkg create ...`
- The devcontainer runs as `root` using `ros:humble` as the base image
- The devcontainer runs as `root` using `lcas.lincoln.ac.uk/ros:humble` as the base image
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README states the devcontainer base image is lcas.lincoln.ac.uk/ros:humble, but the devcontainer Dockerfile defaults to lcas.lincoln.ac.uk/ros:humble-staging. Align the documentation with the actual default (or update the Dockerfile default) so users know exactly what they’re building/running.

Suggested change
- The devcontainer runs as `root` using `lcas.lincoln.ac.uk/ros:humble` as the base image
- The devcontainer runs as `root` using `lcas.lincoln.ac.uk/ros:humble-staging` as the base image

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going back to the point raised initially, we need to create a release upstream to resolve this.

@cooperj cooperj requested a review from a team March 31, 2026 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants