-
Notifications
You must be signed in to change notification settings - Fork 0
Add Dockerfile and GitHub Actions workflow for building AOC Docker images #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
39d0b03
6400cd7
b3e9a40
7f2808b
6e0c408
a1fe98d
a16011a
71f257b
3f967cb
14e9331
728dad1
3749deb
0d530ee
c55cbf2
ac535ef
1a5d2bf
37b628f
2e8ba15
6a10ecd
8d66679
0591fb5
66aed27
14154fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| name: Build a single Docker image (reusable) | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| base_image: | ||
| description: The FROM base image | ||
| required: true | ||
| type: string | ||
| push_image: | ||
| description: Image name on the LCAS registry | ||
| required: true | ||
| type: string | ||
| ros_distro: | ||
| required: true | ||
| type: string | ||
| dockerfile: | ||
| required: true | ||
| type: string | ||
| architectures: | ||
| required: true | ||
| type: string | ||
| outputs: | ||
| digest: | ||
| description: Image digest from the build | ||
| value: ${{ jobs.build.outputs.digest }} | ||
| secrets: | ||
| LCAS_REGISTRY_PUSHER: | ||
| required: true | ||
| LCAS_REGISTRY_TOKEN: | ||
| required: true | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: [lcas, qemu] | ||
| outputs: | ||
| digest: ${{ steps.build.outputs.digest }} | ||
| steps: | ||
| - uses: actions/setup-node@v4 | ||
| - uses: actions/checkout@v3 | ||
| - run: echo "BRANCH=${GITHUB_REF##*/}" >> $GITHUB_ENV | ||
|
|
||
| - uses: docker/login-action@v3 | ||
| with: | ||
| registry: lcas.lincoln.ac.uk | ||
| username: ${{ secrets.LCAS_REGISTRY_PUSHER }} | ||
| password: ${{ secrets.LCAS_REGISTRY_TOKEN }} | ||
|
|
||
| - name: Docker meta | ||
| id: meta | ||
| uses: docker/metadata-action@v5 | ||
| with: | ||
| flavor: latest=false | ||
| labels: | | ||
| org.opencontainers.image.description=AOC Docker Image (${{ inputs.push_image }}, ${{ inputs.ros_distro }}) | ||
| org.opencontainers.image.authors=L-CAS Team | ||
| images: lcas.lincoln.ac.uk/${{ inputs.push_image }} | ||
cooperj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| tags: | | ||
| type=raw,value=${{ inputs.ros_distro }}-staging | ||
| type=raw,enable=${{ github.event_name != 'pull_request' }},value=${{ inputs.ros_distro }}-latest | ||
| type=ref,enable=${{ github.event_name != 'pull_request' }},event=branch,prefix=${{ inputs.ros_distro }}- | ||
| type=semver,pattern={{version}},prefix=${{ inputs.ros_distro }}- | ||
| type=semver,pattern={{major}}.{{minor}},prefix=${{ inputs.ros_distro }}- | ||
| type=semver,pattern={{major}},prefix=${{ inputs.ros_distro }}- | ||
|
|
||
| - uses: docker/setup-buildx-action@v3 | ||
|
|
||
| - name: Build and push | ||
| id: build | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| context: ./docker | ||
| file: ./${{ inputs.dockerfile }} | ||
| platforms: ${{ inputs.architectures }} | ||
| push: true | ||
| cache-from: type=registry,ref=lcas.lincoln.ac.uk/cache/${{ inputs.push_image }}:${{ inputs.ros_distro }} | ||
| cache-to: type=registry,ref=lcas.lincoln.ac.uk/cache/${{ inputs.push_image }}:${{ inputs.ros_distro }},mode=max | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| labels: ${{ steps.meta.outputs.labels }} | ||
| build-args: | | ||
| BASE_IMAGE=${{ inputs.base_image }} | ||
| ROS_DISTRO=${{ inputs.ros_distro }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| name: Build AOC Docker Images | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ main ] | ||
| tags: [ '*' ] | ||
| pull_request: | ||
| branches: [ main ] | ||
| workflow_dispatch: | ||
|
|
||
| jobs: | ||
|
|
||
| # ── Level 0: no dependencies ────────────────────────────────────────────── | ||
|
|
||
| ros-humble: | ||
| uses: ./.github/workflows/_build-image.yaml | ||
| with: | ||
| base_image: ros:humble | ||
| push_image: ros | ||
| ros_distro: humble | ||
| dockerfile: base.dockerfile | ||
| architectures: linux/amd64,linux/arm64 | ||
| secrets: inherit | ||
|
|
||
| ros-jazzy: | ||
| uses: ./.github/workflows/_build-image.yaml | ||
| with: | ||
| base_image: ros:jazzy | ||
| push_image: ros | ||
| ros_distro: jazzy | ||
| dockerfile: base.dockerfile | ||
| architectures: linux/amd64,linux/arm64 | ||
| secrets: inherit | ||
|
|
||
| ros-cuda-humble: | ||
| uses: ./.github/workflows/_build-image.yaml | ||
| with: | ||
| base_image: nvidia/cuda:11.8.0-runtime-ubuntu22.04 | ||
| push_image: ros_cuda | ||
| ros_distro: humble | ||
| dockerfile: cuda.dockerfile | ||
| architectures: linux/amd64 | ||
| secrets: inherit | ||
|
|
||
| ros-cuda-jazzy: | ||
| uses: ./.github/workflows/_build-image.yaml | ||
| with: | ||
| base_image: nvidia/cuda:12.6.3-cudnn-devel-ubuntu24.04 | ||
| push_image: ros_cuda | ||
| ros_distro: jazzy | ||
| dockerfile: cuda.dockerfile | ||
| architectures: linux/amd64 | ||
| secrets: inherit | ||
|
|
||
| # ── Level 1: base_image is the exact digest from level 0 ───────────────── | ||
|
|
||
| ros-cuda-desktop-humble: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should look at how we are naming the components of this, as in it is too easy to confuse I don't believe that the display container should be running ROS directly as this makes it, so the containers need to do more than one thing, breaking the principle of containerisation. The way I propose we do it is like this: #2 I think we should have a simple, slim and efficient way of hydrating a desktop environment to any container.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would propose that we do not use
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The other option is to use a separate deployment target and ship
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not opposed. This was just to indicate the general structure of dependency in workflows not to suggest a specific set of containers yet. The only concern I have is that one cannot have multiple inherence in docker easily. Hence a display with ROS should probably be based on the ros_cuda image? |
||
| needs: ros-cuda-humble | ||
| uses: ./.github/workflows/_build-image.yaml | ||
| with: | ||
| # Digest is immutable — no staging tag, no race condition, no cleanup | ||
| base_image: lcas.lincoln.ac.uk/ros_cuda@${{ needs.ros-cuda-humble.outputs.digest }} | ||
| push_image: ros_cuda_desktop | ||
| ros_distro: humble | ||
| dockerfile: cuda_desktop.dockerfile | ||
| architectures: linux/amd64 | ||
| secrets: inherit | ||
|
|
||
| ros-cuda-desktop-jazzy: | ||
| needs: ros-cuda-jazzy | ||
| uses: ./.github/workflows/_build-image.yaml | ||
| with: | ||
| base_image: lcas.lincoln.ac.uk/ros_cuda@${{ needs.ros-cuda-jazzy.outputs.digest }} | ||
| push_image: ros_cuda_desktop | ||
| ros_distro: jazzy | ||
| dockerfile: cuda_desktop.dockerfile | ||
| architectures: linux/amd64 | ||
| secrets: inherit | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,9 @@ | ||
| # aoc_container_base | ||
| A repository of verstile ROS-enabled Docker containers | ||
|
|
||
| A repository of verstile ROS-enabled Docker containers, orginally developed as apart of the [Agri-OpenCore (AOC) project](https://agri-opencore.org). | ||
|
|
||
| | Container Name | Tags | Purpose | | ||
| | ------------------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | ||
| | `lcas.lincoln.ac.uk/ros` | { `humble`, `jazzy` } | Base ROS Container, the minimal environment you need for ROS | | ||
| | `lcas.lincoln.ac.uk/ros_cuda` | { `humble`, `jazzy` } | ROS + Nvidia. When you need to use a GPU in your ROS environment for either better quality simulation or AI workloads. | | ||
| | `lcas.lincoln.ac.uk/ros_cuda_desktop` | { `humble`, `jazzy` } | ROS + Nvidia + Packages. Installs the `ros-{distro}-desktop` varient so there is the full ROS stack available. | |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| ARG BASE_IMAGE=ros:humble | ||
| ARG ROS_DISTRO=humble | ||
|
|
||
| FROM ${BASE_IMAGE} AS base | ||
| ARG BASE_IMAGE | ||
| ARG ROS_DISTRO | ||
|
|
||
| ENV BASE_IMAGE=${BASE_IMAGE} | ||
| ENV ROS_DISTRO=${ROS_DISTRO} | ||
|
|
||
| ENV DEBIAN_FRONTEND=noninteractive | ||
|
|
||
cooperj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| RUN apt-get update && apt-get upgrade -y && apt-get install -y \ | ||
| build-essential \ | ||
| cmake \ | ||
| git \ | ||
| curl \ | ||
| wget \ | ||
| unzip \ | ||
| ros-${ROS_DISTRO}-ros-base \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| RUN . /opt/ros/${ROS_DISTRO}/setup.sh && rosdep update | ||
|
|
||
| ARG USERNAME=ros | ||
| ARG USER_UID=1001 | ||
| ARG USER_GID=$USER_UID | ||
|
|
||
| # Create a non-root user | ||
| RUN groupadd --gid $USER_GID $USERNAME \ | ||
| && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \ | ||
| # Add sudo support for the non-root user | ||
| && apt-get update \ | ||
| && apt-get install -y --no-install-recommends sudo \ | ||
| && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\ | ||
| && chmod 0440 /etc/sudoers.d/$USERNAME \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| ARG BASE_IMAGE=nvidia/cuda:11.8.0-runtime-ubuntu22.04 | ||
| ARG ROS_DISTRO=humble | ||
|
|
||
|
|
||
| ########################################### | ||
| FROM ${BASE_IMAGE} AS base | ||
| ARG BASE_IMAGE | ||
| ARG ROS_DISTRO | ||
|
|
||
| ENV BASE_IMAGE=${BASE_IMAGE} | ||
| ENV ROS_DISTRO=${ROS_DISTRO} | ||
|
|
||
| ENV DEBIAN_FRONTEND=noninteractive | ||
|
|
||
| # Install language | ||
| RUN apt-get update ; \ | ||
| apt-get upgrade -y && \ | ||
| apt-get install -y --no-install-recommends \ | ||
| locales \ | ||
| curl \ | ||
| gnupg2 \ | ||
| lsb-release \ | ||
| git \ | ||
| nano \ | ||
| python3-setuptools \ | ||
| software-properties-common \ | ||
| wget \ | ||
| tzdata \ | ||
| && locale-gen en_US.UTF-8 \ | ||
| && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
| ENV LANG=en_US.UTF-8 | ||
|
|
||
| RUN curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to ensure we are shipping VirtualGL if we are wanting to use one desktop container and passing windows through, which I think is the best approach. It would allow us to take apps such as Gazebo (the client, not server) and keep that container completely separate to the desktop environment, and using X11 forwarding to handle this.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, as said, the current stub is NOT yet doing all that needs to be done. I only created the skeleton of workflows that allows to build dependent images most efficiently and correctly |
||
| # Prepare ROS2 | ||
| RUN add-apt-repository universe \ | ||
| && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ | ||
| && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null | ||
|
|
||
|
|
||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||
| ros-${ROS_DISTRO}-ros-base \ | ||
| python3-rosdep \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| RUN . /opt/ros/${ROS_DISTRO}/setup.sh && rosdep init && rosdep update | ||
|
|
||
| ARG USERNAME=ros | ||
| ARG USER_UID=1001 | ||
| ARG USER_GID=$USER_UID | ||
|
|
||
| # Create a non-root user | ||
| RUN groupadd --gid $USER_GID $USERNAME \ | ||
| && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \ | ||
| # Add sudo support for the non-root user | ||
| && apt-get update \ | ||
| && apt-get install -y --no-install-recommends sudo \ | ||
| && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\ | ||
| && chmod 0440 /etc/sudoers.d/$USERNAME \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| ARG BASE_IMAGE | ||
|
|
||
| ########################################### | ||
| FROM ${BASE_IMAGE} AS base | ||
|
Check warning on line 4 in cuda_desktop.dockerfile
|
||
|
|
||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||
| ros-${ROS_DISTRO}-desktop \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Upstream this is at v6, check that all steps are up-to-date