Skip to content

Commit

Permalink
Refactor bake config file, much more readable, structured and extendi…
Browse files Browse the repository at this point in the history
…ble, modify Makefile, add initial Dockerfile.deploy
  • Loading branch information
dovvla committed Nov 10, 2024
1 parent aba695d commit 948e886
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 52 deletions.
71 changes: 71 additions & 0 deletions docker/Dockerfile.deploy
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
ARG BASE_IMAGE=osrf/ros:humble-simulation
FROM $BASE_IMAGE

USER root

# Essentials
RUN apt-get update && apt-get install --no-install-recommends -y -o Dpkg::Options::="--force-overwrite" \
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 \
ros-humble-behaviortree-cpp \
libopencv-dev \
# TODO: Question which of these are necessary
python3-pip \
python3-pil \
alsa \
libxshmfence1 \
libgtk-3-dev \
git \
git-lfs \
curl \
wget \
vim \
rsync \
dialog \
fuse

RUN python3 -m pip install scipy transforms3d

#HOTFIX: https://github.com/ros-controls/ros2_controllers/issues/482
RUN wget -O /tmp/diff_drive_controller.deb http://snapshots.ros.org/humble/2022-11-23/ubuntu/pool/main/r/ros-humble-diff-drive-controller/ros-humble-diff-drive-controller_2.12.0-1jammy.20221108.202153_amd64.deb && \
apt install -y --allow-downgrades /tmp/diff_drive_controller.deb && \
rm -f /tmp/diff_drive_controller.deb

# User config
COPY ./config/bashrc /tmp/bashrc

RUN mkdir -p /memristor && \
cat /tmp/bashrc >> /memristor/.bashrc && \
rm -f /tmp/bashrc && \
mkdir -p /memristor/ros2_ws/src/mep3

# Set the working directory
WORKDIR /root/ros2_ws

RUN git clone https://github.com/memristor/mep3 src/mep3

RUN touch src/mep3/mep3_simulation/COLCON_IGNORE

RUN apt-get update && \
apt-get install -y python3-vcstool && \
rosdep update && \
rosdep install --from-paths src --ignore-src -r -y

# Build the packages
RUN . /opt/ros/humble/setup.sh && \
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo

ENTRYPOINT ["/bin/bash", "-c", "source install/local_setup.bash && exec bash"]
64 changes: 46 additions & 18 deletions docker/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
SHELL := $(shell which bash)
.SHELLFLAGS := -eu -o pipefail -c


MAKEFLAGS+=--silent
UID:=$(shell id -u)
DOCKER_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
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 '')
BUILDX_INSTALLED := $(shell docker buildx 1>/dev/null 2>&1 && echo true)
FLAVOR=base
IMAGE=ghcr.io/memristor/mep3

Expand All @@ -21,20 +26,43 @@ vnc:
$(eval IMAGE=ghcr.io/memristor/mep3-vnc)
true

# Docker since version 23.0 has been including buildx by default, current live version is 27.2.1 as of 2024-09-16
build:
docker buildx bake ${FLAVOR}
deploy:
$(eval FLAVOR=deploy)
$(eval IMAGE=ghcr.io/memristor/mep3-deploy)
true

multiple:
$(eval FLAVOR=multiple)
true

# Should be removed in the future, buildx is the new default as per comment above
build_legacy:
echo ${NO_CACHE_ARG}
DOCKER_BUILDKIT=1 docker build ${DOCKER_DIR} -f ${DOCKER_DIR}/Dockerfile.base -t mep3 ${DOCKER_ARGS} --build-arg UID=${UID}
[ ${FLAVOR} != 'base' ] && \
DOCKER_BUILDKIT=1 docker build ${DOCKER_DIR} -f ${DOCKER_DIR}/Dockerfile.${FLAVOR} -t ${IMAGE} ${DOCKER_ARGS} || \
true
## Test if the provided command exists
exists/cmd/%:
@hash $(*) > /dev/null 2>&1 || (echo "ERROR: '$(*)' must be installed"; exit 1)

## Test if the provided environment variable exists
exists/env/%:
@if [ -z '$($(*))' ]; then echo "ERROR: environment variable '$*' not set" && exit 1; fi


# Docker since version 23.0 has been including buildx by default, current live version is 27.2.1 as of 2024-09-16
build: | exists/cmd/docker colors
if [ -n "${BUILDX_INSTALLED}" ]; then \
[ ${FLAVOR} == 'multiple' ] && docker buildx bake && exit 0; \
[ ${FLAVOR} == 'base' ] && docker buildx bake mep3 && exit 0; \
docker buildx bake mep3-${FLAVOR} && exit 0; \
else \
printf '%b\n' "${RED}Docker buildx is not present, it is highly recommended to install newer version of docker\n${NC}" || \
[ ${FLAVOR} = 'multiple' ] && \
DOCKER_BUILDKIT=1 docker build ${DOCKER_DIR} -f ${DOCKER_DIR}/Dockerfile.base -t mep3 ${DOCKER_ARGS} --build-arg UID=${UID} && \
DOCKER_BUILDKIT=1 docker build ${DOCKER_DIR} -f ${DOCKER_DIR}/Dockerfile.vnc -t mep3-vnc ${DOCKER_ARGS} && \
DOCKER_BUILDKIT=1 docker build ${DOCKER_DIR} -f ${DOCKER_DIR}/Dockerfile.deploy -t mep3-deploy ${DOCKER_ARGS} && exit 0; \
[ ${FLAVOR} = 'base' ] && \
DOCKER_BUILDKIT=1 docker build ${DOCKER_DIR} -f ${DOCKER_DIR}/Dockerfile.${FLAVOR} -t mep3 ${DOCKER_ARGS} --build-arg UID=${UID} && exit 0; \
[ ${FLAVOR} != 'base' ] && \
DOCKER_BUILDKIT=1 docker build ${DOCKER_DIR} -f ${DOCKER_DIR}/Dockerfile.${FLAVOR} -t mep3-${FLAVOR} ${DOCKER_ARGS} && exit 0; \
fi

run: test-nvidia
run: | exists/cmd/docker test-nvidia
docker run \
--net=host \
--ipc=host \
Expand All @@ -51,7 +79,7 @@ run: test-nvidia
-v ${PROJECT_DIR}:/memristor/ros2_ws/src/mep3:rw \
-d -it ${IMAGE} 1>/dev/null

test-nvidia: colors
test-nvidia: | exists/cmd/docker
lspci | grep -qi nvidia && base64 --decode massage | unxz || true
docker run --rm \
-e NVIDIA_DRIVER_CAPABILITIES=all ${NVIDIA_GPU} \
Expand All @@ -60,26 +88,26 @@ test-nvidia: colors
printf '%b\n' "${RED}Detected NVIDIA GPU in system, but missing packets, look up NVIDIA GPU section in README!\n${NC}" || \
true

start-code-server:
start-code-server: | exists/cmd/docker
docker exec -d -it mep3-${FLAVOR} bash -c 'pgrep code-server || code-server /memristor/ros2_ws/src/mep3' && \
xdg-open 'localhost:31415?folder=/memristor/ros2_ws/src/mep3'

stop-code-server:
stop-code-server: | exists/cmd/docker
docker exec -it mep3-${FLAVOR} pkill -f code-server

exec:
exec: | exists/cmd/docker
docker exec -it mep3-${FLAVOR} bash

destroy:
destroy: | exists/cmd/docker
docker container kill mep3-${FLAVOR} 1>/dev/null || true
docker container rm -f mep3-${FLAVOR} 1>/dev/null || true

setup-default: colors
setup-default: | exists/cmd/docker colors
docker exec -it mep3-${FLAVOR} sh -c '/usr/bin/setup.sh --default'
printf '%b\n%b\n' "${GREEN}Default setup complete!${NC}" \
"Run ${BOLD}make exec${NC} or ${BOLD}docker exec -it mep3-${FLAVOR}${NC} to access the container"

setup-interactive: colors
setup-interactive: | exists/cmd/docker colors
docker exec -it mep3-${FLAVOR} sh -c '/usr/bin/setup.sh --interactive'
printf '%b\n%b\n' "${GREEN}Interactive setup complete!${NC}" \
"Run ${BOLD}make exec${NC} or ${BOLD}docker exec -it mep3-${FLAVOR}${NC} to access the container"
68 changes: 34 additions & 34 deletions docker/docker-bake.hcl
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
group "default" {
targets = ["base", "vnc"]
}

variable "COMMIT_SHA" {}

variable "GITHUB_REPO" {}

target "base" {
context = "."
dockerfile = "Dockerfile.base"
tags = [
// If GITHUB_REPO is not set, then we are building locally
equal("", GITHUB_REPO) ? "mep3:latest" : "",
equal("", GITHUB_REPO) && notequal("", COMMIT_SHA) ? "mep3:${COMMIT_SHA}" : "",
notequal("", GITHUB_REPO) ? "ghcr.io/${GITHUB_REPO}/mep3:latest" : "",
notequal("", GITHUB_REPO) && notequal("", COMMIT_SHA) ? "ghcr.io/${GITHUB_REPO}:${COMMIT_SHA}" : ""
]
// Enable layer caching
cache-from = ["type=gha,scope=mep3"]
cache-to = ["type=gha,mode=max,scope=mep3"]
// for reference, can be passed the same way as --build-arg, this can be completely omitted, and in this configuration will default to values specified in Dockerfile
args = {
DEBIAN_FRONTEND = null,
UID = null,
variable "TARGET_IMAGE_NAME_MAPPING" {
default = {
"base" = "mep3"
"vnc" = "mep3-vnc"
"deploy" = "mep3-deploy"
}
}

target "vnc" {
context = "."
dockerfile = "Dockerfile.vnc"
contexts = {
mep3 = "target:base"
variable CONTEXTS_MAPPING {
default = {
"vnc" = {
"mep3" = "target:mep3"
}
}
tags = [
}

function "eval_tags" {
params = [image_name, commit_sha, github_repo]
result = [
// If GITHUB_REPO is not set, then we are building locally
equal("", GITHUB_REPO) ? "mep3-vnc:latest" : "",
equal("", GITHUB_REPO) && notequal("", COMMIT_SHA) ? "mep3-vnc:${COMMIT_SHA}" : "",
notequal("", GITHUB_REPO) ? "ghcr.io/${GITHUB_REPO}/mep3-vnc:latest" : "",
notequal("", GITHUB_REPO) && notequal("", COMMIT_SHA) ? "ghcr.io/${GITHUB_REPO}-vnc:${COMMIT_SHA}" : ""
equal("", github_repo) ? image_name : "",
equal("", github_repo) && notequal("", commit_sha) ? "${image_name}:${commit_sha}" : "",
// otherwise, we are building on GitHub Actions
notequal("", github_repo) ? "ghcr.io/${github_repo}/${image_name}:latest" : "",
notequal("", github_repo) && notequal("", commit_sha) ? "ghcr.io/${github_repo}:${commit_sha}" : ""
]
// Enable layer caching
cache-from = ["type=gha,scope=mep3-vnc"]
cache-to = ["type=gha,mode=max,scope=mep3-vnc"]
}

target "default" {
name = lookup(TARGET_IMAGE_NAME_MAPPING, tgt, "")
matrix = {
tgt = keys(TARGET_IMAGE_NAME_MAPPING)
}

tags = eval_tags(lookup(TARGET_IMAGE_NAME_MAPPING, tgt, ""), COMMIT_SHA, GITHUB_REPO)
dockerfile = "Dockerfile.${tgt}"
cache-to = [format("%s%s", "type=gha,mode=max,scope=", lookup(TARGET_IMAGE_NAME_MAPPING, tgt, ""))]
cache-from = [format("%s%s", "type=gha,scope=", lookup(TARGET_IMAGE_NAME_MAPPING, tgt, ""))]

contexts = lookup(CONTEXTS_MAPPING, tgt, {})
}

0 comments on commit 948e886

Please sign in to comment.