Skip to content

Refactor Devcontainer Dockerfile (Root User/Bind Mounts) and Restores GitHub Actions Workflows#19

Merged
cooperj merged 7 commits intomainfrom
cooperj/apr27
Apr 27, 2026
Merged

Refactor Devcontainer Dockerfile (Root User/Bind Mounts) and Restores GitHub Actions Workflows#19
cooperj merged 7 commits intomainfrom
cooperj/apr27

Conversation

@cooperj
Copy link
Copy Markdown
Member

@cooperj cooperj commented Apr 27, 2026

This pull request resolves issues #17 and #18, by fixing the development container setup and its associated GitHub Actions workflow. The changes focus on improving the Dockerfile for the devcontainer and modifying the workflow configuration for building the development container image.

Devcontainer Dockerfile improvements:

  • Switched to running installation steps as root and then reverting to the main user for subsequent commands, improving security and aligning with best practices. (.devcontainer/Dockerfile)
  • Changed the rosdep install command to use a bind mount for /workspace, ensuring dependencies are installed from the correct path. (.devcontainer/Dockerfile)

GitHub Actions workflow changes:

  • Removed build cache options (cacheFrom and cacheTo) from the devcontainer build step, possibly to simplify the workflow or address caching issues. (.github/workflows/dev-container.yml)
  • Renamed the workflow file from .github/workflows/dev-container.yml.off to .github/workflows/dev-container.yml, re-enabling the workflow.

@cooperj cooperj self-assigned this Apr 27, 2026
@cooperj cooperj changed the title Cooperj/apr27 Refactor Devcontainer Dockerfile (Root User/Bind Mounts) and Restores GitHub Actions Workflows Apr 27, 2026
@cooperj cooperj added the bug Something isn't working label Apr 27, 2026
@cooperj cooperj requested a review from Copilot April 27, 2026 12:29
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 aims to fix the devcontainer build by running privileged install steps as root, avoid copying the entire workspace into the devcontainer image by using BuildKit bind mounts, and re-enable/adjust GitHub Actions workflows for devcontainer and Docker image builds.

Changes:

  • Refactors .devcontainer/Dockerfile to run apt installs as root, switch users, and use a bind mount for rosdep install instead of copying the whole repo.
  • Re-enables/adds GitHub Actions workflows for ROS CI and Docker image builds, and simplifies the devcontainer CI build step by removing cache configuration.
  • Adds a GHCR build/push workflow for the “final” Docker image target.

Reviewed changes

Copilot reviewed 2 out of 4 changed files in this pull request and generated 2 comments.

File Description
.devcontainer/Dockerfile Switches to root for apt, uses bind mount for rosdep, and keeps devcontainer/final stages.
.github/workflows/dev-container.yml Removes build cache configuration from the devcontainer CI action invocation.
.github/workflows/ros-ci.yml Adds a ROS CI workflow running builds in container images for multiple ROS distros.
.github/workflows/build-docker.yml Adds a workflow to build/push the “final” Docker image to GHCR with metadata and caching.
Comments suppressed due to low confidence (1)

.devcontainer/Dockerfile:34

  • The COPY ./ /workspace/ was removed, but the image still runs colcon build in this stage and again in the final stage. Without copying (or bind-mounting) the workspace for those build steps, /workspace/src and /workspace/install won’t exist in the built image, and the CMD that sources /workspace/install/setup.bash will fail. Recommended: keep the bind-mount approach for rosdep in the devcontainer stage, but add a COPY (or at least COPY src/) in the final stage before colcon build, and either remove the initial build in devcontainer or also run it with a bind mount.
WORKDIR /workspace
ENV ROS2_WS=/workspace
RUN --mount=type=bind,source=.,target=/workspace \
    rosdep update --rosdistro ${ROS_DISTRO} &&\
    apt-get update && \
    rosdep install --from-paths /workspace/src --ignore-src -r -y


# Do an initial build to speed up development
RUN /bin/bash -lc "source /opt/ros/${ROS_DISTRO}/setup.bash && colcon build --continue-on-error"

# ----------------------------------------------------------------------------------------------------
FROM devcontainer AS final

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"]

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

Comment thread .devcontainer/Dockerfile Outdated
Comment on lines +6 to +16
ENV main_user=${USER}

USER root
RUN rm -rf /var/lib/apt/lists/* \
&& apt-get update --fix-missing \
&& apt-get -y install --no-install-recommends --fix-missing \
ros-${ROS_DISTRO}-desktop \
bash-completion \
&& rm -rf /var/lib/apt/lists/*

COPY ./ /workspace/
WORKDIR /workspace
USER ${main_user}
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

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

ENV main_user=${USER} is likely to expand to an empty value during build (the base image may not define a USER environment variable). That can make USER ${main_user} invalid and break the build. Consider explicitly setting the intended username via an ARG (with a sane default like root) or hard-coding the user you want to switch back to, rather than relying on $USER.

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

Choose a reason for hiding this comment

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

@cooperj copilot is right... we need to ensure that main_user is set to a value, so I suggest

ENV main_user=${USER:-root}

so that if no $USER is defined it is set to root

Comment thread .devcontainer/Dockerfile Outdated
Comment on lines +16 to +23
USER ${main_user}

WORKDIR /workspace
ENV ROS2_WS=/workspace
RUN rosdep update --rosdistro ${ROS_DISTRO} &&\
RUN --mount=type=bind,source=.,target=/workspace \
rosdep update --rosdistro ${ROS_DISTRO} &&\
apt-get update && \
rosdep install --from-paths ./src --ignore-src -r -y
rosdep install --from-paths /workspace/src --ignore-src -r -y
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

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

After switching away from root (USER ${main_user}), this layer runs apt-get update (and rosdep install typically installs apt packages). If main_user is non-root, this will fail with the same apt permissions issue the PR is trying to fix. Keep this RUN step as root (or use sudo) and only switch users after dependency installation completes.

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

Choose a reason for hiding this comment

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

again, copilot is right, this part must be executed in the part where we have root permission NOT after we switch back to $main_user.

@cooperj cooperj requested a review from marc-hanheide April 27, 2026 12:35
@cooperj cooperj marked this pull request as ready for review April 27, 2026 12:35
Comment thread .devcontainer/Dockerfile Outdated
Comment on lines +6 to +16
ENV main_user=${USER}

USER root
RUN rm -rf /var/lib/apt/lists/* \
&& apt-get update --fix-missing \
&& apt-get -y install --no-install-recommends --fix-missing \
ros-${ROS_DISTRO}-desktop \
bash-completion \
&& rm -rf /var/lib/apt/lists/*

COPY ./ /workspace/
WORKDIR /workspace
USER ${main_user}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@cooperj copilot is right... we need to ensure that main_user is set to a value, so I suggest

ENV main_user=${USER:-root}

so that if no $USER is defined it is set to root

Comment thread .devcontainer/Dockerfile Outdated
Comment on lines +16 to +23
USER ${main_user}

WORKDIR /workspace
ENV ROS2_WS=/workspace
RUN rosdep update --rosdistro ${ROS_DISTRO} &&\
RUN --mount=type=bind,source=.,target=/workspace \
rosdep update --rosdistro ${ROS_DISTRO} &&\
apt-get update && \
rosdep install --from-paths ./src --ignore-src -r -y
rosdep install --from-paths /workspace/src --ignore-src -r -y
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

again, copilot is right, this part must be executed in the part where we have root permission NOT after we switch back to $main_user.

Comment thread .github/workflows/dev-container.yml
Comment thread .devcontainer/Dockerfile Outdated
RUN rm -rf /var/lib/apt/lists/* \
&& apt-get update --fix-missing \
&& apt-get -y install --no-install-recommends --fix-missing \
ros-${ROS_DISTRO}-desktop \
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why are we installing the very big desktop here? I would only install ros-${ROS_DISTRO}-base. Everything else should be handled with rosdep install below.

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.

ros-{distro}-desktop was originally placed here to be a placeholder for things to be installed allowing for general packages to be tested (i.e. Rviz).

-base is installed in image base image creation, would it be wiser to just not execute it here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ros-{distro}-desktop was originally placed here to be a placeholder for things to be installed allowing for general packages to be tested (i.e. Rviz).

-base is installed in image base image creation, would it be wiser to just not execute it here?

Yes, I think we don't want it here as it hides incomplete package.xml dependencies

@cooperj cooperj requested a review from marc-hanheide April 27, 2026 13:15
@cooperj cooperj merged commit ca87b9f into main Apr 27, 2026
4 checks passed
@cooperj cooperj deleted the cooperj/apr27 branch April 27, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants