From a01fff3e64e814eeb3828a6edcbeac72c05f7bd2 Mon Sep 17 00:00:00 2001 From: Vladimir Jovin <58534614+dovvla@users.noreply.github.com> Date: Tue, 12 Dec 2023 00:05:55 +0100 Subject: [PATCH] Add Github Actions for building images for environments (#282) Add two workflows, rather one reusable workflow. This reusable workflow builds both local and vnc development image (vnc image is based on the built local image), Trigger this workflow everytime there is a change detected in workflow spec YAMLs, or in the docker dir. Add context to docker README file. --- .../build_and_push_image_workflow.yml | 63 ++++++++++++++++ .github/workflows/build_and_push_images.yml | 18 +++++ docker/Dockerfile.base | 73 ++++++++++--------- docker/Dockerfile.vnc | 25 ++++--- docker/Makefile | 10 ++- docker/README.md | 10 ++- 6 files changed, 148 insertions(+), 51 deletions(-) create mode 100644 .github/workflows/build_and_push_image_workflow.yml create mode 100644 .github/workflows/build_and_push_images.yml diff --git a/.github/workflows/build_and_push_image_workflow.yml b/.github/workflows/build_and_push_image_workflow.yml new file mode 100644 index 000000000..daf9708b6 --- /dev/null +++ b/.github/workflows/build_and_push_image_workflow.yml @@ -0,0 +1,63 @@ +name: Deploy Images to GHCR + +on: + workflow_call: + inputs: + flavor: + required: false + default: "devel" + type: string + base_image: + required: false + default: "osrf/ros:humble-desktop" + type: string + +jobs: + push-mep3-image: + runs-on: ubuntu-latest + defaults: + run: + working-directory: "./docker" + + steps: + - name: "Checkout GitHub Action" + uses: actions/checkout@main + + - name: "Login to GitHub Container Registry" + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{github.actor}} + password: ${{secrets.GITHUB_TOKEN}} + + - name: "Configure Docker parameters" + id: configure_docker_params + run: | + #!/bin/bash + + case ${{inputs.flavor}} in + "vnc") + echo "dockerfile=Dockerfile.vnc" >> $GITHUB_OUTPUT + echo "image_name=mep3-vnc" >> $GITHUB_OUTPUT + ;; + *) + echo "dockerfile=Dockerfile.base" >> $GITHUB_OUTPUT + echo "image_name=mep3" >> $GITHUB_OUTPUT + ;; + esac + + - uses: docker/setup-buildx-action@v3 + + - name: Build and Push Docker Image + uses: docker/build-push-action@v5 + with: + context: docker + file: ./docker/${{ steps.configure_docker_params.outputs.dockerfile }} + build-args: | + BASE_IMAGE=${{ inputs.base_image }} + push: true + tags: | + ghcr.io/${{ github.repository_owner }}/${{ steps.configure_docker_params.outputs.image_name }}:latest + ghcr.io/${{ github.repository_owner }}/${{ steps.configure_docker_params.outputs.image_name }}:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/build_and_push_images.yml b/.github/workflows/build_and_push_images.yml new file mode 100644 index 000000000..0f371f124 --- /dev/null +++ b/.github/workflows/build_and_push_images.yml @@ -0,0 +1,18 @@ +on: + push: + branches: + - main + paths: + - "docker/**" + - ".github/workflows/build_and_push_image_workflow.yml" + - ".github/workflows/build_and_push_images.yml" +jobs: + build-base: + uses: ./.github/workflows/build_and_push_image_workflow.yml + notify: + needs: build-base + name: build-vnc + uses: ./.github/workflows/build_and_push_image_workflow.yml + with: + flavor: vnc + base_image: "ghcr.io/${{ github.repository }}:${{ github.sha }}" diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index d4c76546a..5390f977d 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -1,51 +1,52 @@ -FROM osrf/ros:humble-desktop +ARG BASE_IMAGE=osrf/ros:humble-desktop +FROM $BASE_IMAGE ARG DEBIAN_FRONTEND=noninteractive ARG UID=1000 # User RUN useradd -d /memristor -m \ - -u $UID -U \ - -s /usr/bin/bash \ - -G dialout \ - -c "Memristor Robotics" memristor && \ + -u $UID -U \ + -s /usr/bin/bash \ + -G dialout \ + -c "Memristor Robotics" memristor && \ echo "memristor ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers # Essentials RUN apt-get update && apt-get install -y \ - ros-humble-navigation2 \ - ros-humble-nav2-bringup \ - ros-humble-rviz2 \ - ros-humble-teleop-twist-keyboard \ - ros-humble-dynamixel-sdk \ - ros-humble-can-msgs \ - ros-humble-ruckig \ - ros-humble-laser-filters \ - ros-humble-domain-bridge \ - ros-humble-rmw-cyclonedds-cpp \ - ros-humble-ros2-control \ - ros-humble-ros2-controllers \ - ros-humble-rqt-common-plugins \ - ros-humble-webots-ros2 \ - ros-humble-dynamixel-workbench-toolbox \ - libopencv-dev \ - python3-pip \ - python3-pil \ - alsa \ - libxshmfence1 \ - libgtk-3-dev \ - git \ - git-lfs \ - curl \ - wget \ - vim \ - rsync \ - dialog \ - fish + ros-humble-navigation2 \ + ros-humble-nav2-bringup \ + ros-humble-rviz2 \ + ros-humble-teleop-twist-keyboard \ + ros-humble-dynamixel-sdk \ + ros-humble-can-msgs \ + ros-humble-ruckig \ + ros-humble-laser-filters \ + ros-humble-domain-bridge \ + ros-humble-rmw-cyclonedds-cpp \ + ros-humble-ros2-control \ + ros-humble-ros2-controllers \ + ros-humble-rqt-common-plugins \ + ros-humble-webots-ros2 \ + ros-humble-dynamixel-workbench-toolbox \ + libopencv-dev \ + python3-pip \ + python3-pil \ + alsa \ + libxshmfence1 \ + libgtk-3-dev \ + git \ + git-lfs \ + curl \ + wget \ + vim \ + rsync \ + dialog \ + fish # VS Code RUN curl -L -o /tmp/vscode.deb \ - 'https://code.visualstudio.com/sha/download?build=stable&os=linux-deb-x64' && \ + 'https://code.visualstudio.com/sha/download?build=stable&os=linux-deb-x64' && \ apt-get install -y /tmp/vscode.deb && \ rm -f /tmp/vscode.deb @@ -57,7 +58,7 @@ RUN su memristor -c 'code --install-extension eamodio.gitlens' && \ # Webots RUN curl -L -o /tmp/webots.deb \ - 'https://github.com/cyberbotics/webots/releases/download/R2023a/webots_2023a_amd64.deb' && \ + 'https://github.com/cyberbotics/webots/releases/download/R2023a/webots_2023a_amd64.deb' && \ apt-get install -y /tmp/webots.deb && \ rm -f /tmp/webots.deb && \ mkdir -p /memristor/.config/Cyberbotics diff --git a/docker/Dockerfile.vnc b/docker/Dockerfile.vnc index 4767f90be..477adcc18 100644 --- a/docker/Dockerfile.vnc +++ b/docker/Dockerfile.vnc @@ -1,34 +1,35 @@ -FROM mep3 +ARG BASE_IMAGE=ghcr.io/memristor/mep3 +FROM $BASE_IMAGE USER root # TurboVNC RUN curl -L -o /tmp/turbovnc.deb \ - 'https://downloads.sourceforge.net/project/turbovnc/3.0.1/turbovnc_3.0.1_amd64.deb?use_mirror=autoselect' && \ + 'https://downloads.sourceforge.net/project/turbovnc/3.0.1/turbovnc_3.0.1_amd64.deb?use_mirror=autoselect' && \ apt-get install -y /tmp/turbovnc.deb && \ rm -f /tmp/turbovnc.deb && \ - echo 'PATH="$PATH:/opt/TurboVNC/bin"' >> /memristor/.bashrc + echo 'PATH="$PATH:/opt/TurboVNC/bin"' >> /memristor/.bashrc # VirtualGL RUN curl -L -o /tmp/virtualgl.deb \ - 'https://downloads.sourceforge.net/project/virtualgl/3.0.2/virtualgl_3.0.2_amd64.deb?use_mirror=autoselect' && \ + 'https://downloads.sourceforge.net/project/virtualgl/3.0.2/virtualgl_3.0.2_amd64.deb?use_mirror=autoselect' && \ apt-get install -y /tmp/virtualgl.deb && \ rm -f /tmp/virtualgl.deb && \ - echo 'PATH="$PATH:/opt/VirtualGL/bin"' >> /memristor/.bashrc && \ - printf "1\n\n\n\nX" | /opt/VirtualGL/bin/vglserver_config && \ - sudo usermod -a -G vglusers memristor + echo 'PATH="$PATH:/opt/VirtualGL/bin"' >> /memristor/.bashrc && \ + printf "1\n\n\n\nX" | /opt/VirtualGL/bin/vglserver_config && \ + sudo usermod -a -G vglusers memristor # NoVNC RUN apt-get install -y novnc && \ - ln -sf /usr/share/novnc/vnc.html /usr/share/novnc/index.html && \ + ln -sf /usr/share/novnc/vnc.html /usr/share/novnc/index.html && \ mkdir -p /memristor/.host # XFCE RUN apt-get install -y --no-install-recommends \ - xorg \ - dbus-x11 \ - xfce4 \ - xfce4-terminal && \ + xorg \ + dbus-x11 \ + xfce4 \ + xfce4-terminal && \ echo '/usr/sbin/lightdm' > /etc/X11/default-display-manager # User config diff --git a/docker/Makefile b/docker/Makefile index 2803f4fd2..9aa289b03 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -4,10 +4,11 @@ PROJECT_DIR:=$(shell dirname ${DOCKER_DIR}) NVIDIA_GPU:=$(shell (docker info | grep Runtimes | grep nvidia 1> /dev/null && command -v nvidia-smi 1>/dev/null 2>/dev/null && nvidia-smi | grep Processes 1>/dev/null 2>/dev/null) && echo '--runtime nvidia --gpus all' || echo '') FLAVOR=devel IMAGE=mep3 +IMAGE_URL=ghcr.io/memristor/mep3 .PHONY: all -all: destroy build run setup exec +all: destroy build run setup exec pull vnc: $(eval FLAVOR=vnc) @@ -23,6 +24,13 @@ build: @[ ${FLAVOR} != 'devel' ] && \ DOCKER_BUILDKIT=1 docker build ${DOCKER_DIR} -f ${DOCKER_DIR}/Dockerfile.${FLAVOR} -t ${IMAGE} ${DOCKER_ARGS} || \ true + +pull: + @docker pull ${IMAGE_URL} + @[ ${FLAVOR} != 'devel' ] && \ + docker pull ${IMAGE_URL}-${FLAVOR} || \ + true + run: @docker run \ --net=host \ diff --git a/docker/README.md b/docker/README.md index a4cd7dd03..87c6bdbc7 100644 --- a/docker/README.md +++ b/docker/README.md @@ -13,7 +13,13 @@ # Make sure to have your SSH keys added to GitHub git clone git@github.com:memristor/mep3.git ``` -3) Run provisioning script to build and run the container + +3) Run provisioning script to build and run the container: + ```sh + cd ./mep3/docker + make pull run + ``` + Alternatively, if you prefer, you can build the image locally on your machine: ```sh cd ./mep3/docker make build run @@ -42,7 +48,7 @@ `make` in steps 4 and 6 (eg. `make vnc setup`) 2) Enable VNC preferences in step 6 and wait for the container to restart 3) Web-based VNC client will be accessible at `http://localhost:6810/` if you keep default noVNC webserver port -4) In step 7 replace `mep3-devel` with `mep3-vnc` +4) In step 6 replace `mep3-devel` with `mep3-vnc` **Note:** If you are setting up through SSH, make sure to have a running Xorg server on host machine, and set `DISPLAY` environment variable on step 4 to its value (eg `:0`).