Skip to content

Commit

Permalink
Merge pull request - Container Integration
Browse files Browse the repository at this point in the history
Makefile and Dockerfiles for CPU/CUDA/Jetson
  • Loading branch information
EmilianoHFlores authored Apr 2, 2024
2 parents a54475d + d57b5a1 commit b957870
Show file tree
Hide file tree
Showing 8 changed files with 524 additions and 2 deletions.
73 changes: 73 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# ----------------------------------------------------------------------
# Robocup@Home ROS Noetic Docker Development
# ----------------------------------------------------------------------

#: Builds a Docker image with the corresponding Dockerfile file

# ----------------------------BUILD------------------------------------
# ---------Main----------
# No GPU
main.build:
@./docker/scripts/build.bash --area=main

# CUDA 11.8 x86_64
main.build.cuda:
@./docker/scripts/build.bash --area=main --use-cuda

# Jetson devices
main.build.jetson:
@./docker/scripts/build.bash --area=main --jetson-l4t=35.4.1

# ----------------------------CREATE------------------------------------

main.create:
@./docker/scripts/run.bash --area=main --volumes=$(volumes) --name=$(name)

main.create.cuda:
@./docker/scripts/run.bash --area=main --use-cuda --volumes=$(volumes) --name=$(name)

# For jetpack version 35.4.1, jetson images are special in the sense that they are specific to the jetpack version
main.create.jetson:
@./docker/scripts/run.bash --area=main --jetson-l4t=35.4.1 --volumes=$(volumes) --name=$(name)

# ----------------------------START------------------------------------
# Start containers
main.up:
@xhost +
@docker start home-main

# ----------------------------STOP------------------------------------
# Stop containers
main.down:
@docker stop home-main

# ----------------------------RESTART------------------------------------
# Restart containers
main.restart:
@docker restart home-main

# ----------------------------LOGS------------------------------------
# Logs of the container
main.logs:
@docker logs --tail 50 home-main

# ----------------------------SHELL------------------------------------
# Fires up a bash session inside the container
main.shell:
@docker exec -it --user $(shell id -u):$(shell id -g) home-main bash

# ----------------------------REMOVE------------------------------------
# Remove container
main.remove:
@docker container rm home-main

# ----------------------------------------------------------------------
# General Docker Utilities

#: Show a list of images.
list-images:
@docker image ls

#: Show a list of containers.
list-containers:
@docker container ls -as
48 changes: 47 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,58 @@ And to update the submodules content execute:
git submodule update --init --recursive
```

All the development environments use Docker, follow the instructions inside the `docker` folders.
All the development environments use Docker, follow the instructions below or the [README](docker/README.md) inside the `docker` folder for insights.

## Software Architecture

![home-2](https://github.com/RoBorregos/home/assets/25570636/ea6f9551-27c7-4b4e-8fcb-8733a6eb7284)

## Docker Development
The project uses Docker for easier development within ROS and CUDA/Jetson compatibility. Both this main engine repository and each area's contain a `docker` folder with dockerfiles and a Makefile for easier image and container creation and modification.
### Requirements

- [Docker Engine](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository)
- [Post-installation steps for Linux](https://docs.docker.com/engine/install/linux-postinstall/)
If using GPU:
- NVIDIA Driver
- [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/index.html))
### Container Creation
To build an image, run:

```bash
# For CPU
make main.build
# For GPU
make main.build.cuda
# For Jetson L4T: 35.4.1
make main.build.jetson
```
To create a container, run the following commands. The `ws` folder is mounted by default, and additional folders can be added with the `volumes` argument, with both absolute and relative paths allowed:

```bash
# For CPU
make main.create volumes="another_folder1/,~/another_folder2"
# For GPU
make main.create.cuda volumes="another_folder1/,~/another_folder2"
# For Jetson L4T: 35.4.1
make main.create.jetson volumes="another_folder1/,~/another_folder2"
```

To enter the container, run:

```bash
make main.up
make main.shell
```

You can stop and remove the container with:

```bash
make main.down
make main.remove
```

Additional commands can be added within the Makefile and the scripts inside the `docker/scripts` folder can help for easier integration and sharing. These include a build script to run the dockerfile and create a new image and a run script to create containers from it. Any additional dependency or system/environment configuration should be added to these scripts.
## Team Members

| Name | Github | Role |
Expand Down
23 changes: 23 additions & 0 deletions docker/Dockerfile.main
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM althack/ros:noetic-full AS base
LABEL maintainer="RoBorregos <[email protected]>"
# Install dependencies.
RUN apt-get update -qq && apt-get install -y build-essential \
ffmpeg libsm6 libxext6 autoconf libtool mesa-utils \
terminator nano git wget curl iputils-ping \
libcanberra-gtk-module libcanberra-gtk3-module \
ros-dev-tools

RUN apt-get update && apt-get install -y ros-noetic-rqt ros-noetic-rqt-common-plugins

# New stage for each feature added
############################################
# Foxglove bridge
############################################

FROM base as foxglove
# Install dependencies.
RUN apt install -y ros-noetic-foxglove-bridge

RUN echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc

ENTRYPOINT [ "/bin/bash", "-l", "-c" ]
169 changes: 169 additions & 0 deletions docker/Dockerfile.main.cuda
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#############################################
# Created from althack/ros:noetic
#############################################

###########################################
# Base image
###########################################
FROM nvidia/cuda:11.8.0-runtime-ubuntu20.04 AS base

LABEL maintainer="RoBorregos <[email protected]>"

ENV DEBIAN_FRONTEND=noninteractive

# Install language
RUN apt-get update && apt-get install -y \
locales \
&& 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

# Install timezone
RUN ln -fs /usr/share/zoneinfo/UTC /etc/localtime \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get install -y tzdata \
&& dpkg-reconfigure --frontend noninteractive tzdata \
&& rm -rf /var/lib/apt/lists/*

# Install ROS
RUN apt-get update && apt-get install -y \
curl \
dirmngr \
gnupg2 \
lsb-release \
sudo \
&& sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' \
&& curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add - \
&& apt-get update && apt-get install -y \
ros-noetic-ros-base \
&& rm -rf /var/lib/apt/lists/*

# Setup environment
ENV LD_LIBRARY_PATH=/opt/ros/noetic/lib
ENV ROS_DISTRO=noetic
ENV ROS_ROOT=/opt/ros/noetic/share/ros
ENV ROS_PACKAGE_PATH=/opt/ros/noetic/share
ENV ROS_MASTER_URI=http://localhost:11311
ENV ROS_PYTHON_VERSION=3
ENV ROS_VERSION=1
ENV PATH=/opt/ros/noetic/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV ROSLISP_PACKAGE_DIRECTORIES=
ENV PYTHONPATH=/opt/ros/noetic/lib/python3/dist-packages
ENV PKG_CONFIG_PATH=/opt/ros/noetic/lib/pkgconfig
ENV ROS_ETC_DIR=/opt/ros/noetic/etc/ros
ENV CMAKE_PREFIX_PATH=/opt/ros/noetic
ENV DEBIAN_FRONTEND=

# New stage for each feature added
###########################################
# Develop image
###########################################
FROM base AS dev

ENV DEBIAN_FRONTEND=noninteractive
# Install dev tools
RUN apt-get update && apt-get install -y \
python3-rosdep \
python3-rosinstall \
python3-rosinstall-generator \
python3-wstool \
python3-pip \
python3-pep8 \
python3-autopep8 \
pylint3 \
build-essential \
bash-completion \
git \
vim \
&& rm -rf /var/lib/apt/lists/* \
&& rosdep init || echo "rosdep already initialized"

ARG USERNAME=ros
ARG USER_UID=1000
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 sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\
&& chmod 0440 /etc/sudoers.d/$USERNAME \
&& rm -rf /var/lib/apt/lists/*

# Set up autocompletion for user
RUN apt-get update && apt-get install -y git-core bash-completion \
&& echo "if [ -f /opt/ros/${ROS_DISTRO}/setup.bash ]; then source /opt/ros/${ROS_DISTRO}/setup.bash; fi" >> /home/$USERNAME/.bashrc \
&& echo "if [ -f /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash ]; then source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash; fi" >> /home/$USERNAME/.bashrc \
&& rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND=

###########################################
# Full image
###########################################
FROM dev AS full

ENV DEBIAN_FRONTEND=noninteractive
# Install the full release
RUN apt-get update && apt-get install -y \
ros-noetic-desktop \
&& rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND=

###########################################
# Full+Gazebo image
###########################################
FROM full AS gazebo

ENV DEBIAN_FRONTEND=noninteractive
# Install gazebo
RUN apt-get update && apt-get install -y \
ros-noetic-gazebo* \
&& rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND=

###########################################
# Full+Gazebo+Nvidia image
###########################################

FROM gazebo AS gazebo-nvidia

################
# Expose the nvidia driver to allow opengl
# Dependencies for glvnd and X11.
################
RUN apt-get update \
&& apt-get install -y -qq --no-install-recommends \
libglvnd0 \
libgl1 \
libglx0 \
libegl1 \
libxext6 \
libx11-6

# Env vars for the nvidia-container-runtime.
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES graphics,utility,compute
ENV QT_X11_NO_MITSHM 1

# Install dependencies.
RUN apt-get update -qq && apt-get install -y build-essential \
ffmpeg libsm6 libxext6 autoconf libtool mesa-utils \
terminator nano git wget curl iputils-ping \
libcanberra-gtk-module libcanberra-gtk3-module \
ros-dev-tools ros-noetic-teleop-twist-keyboard

# # Gazebo classic install
# RUN apt install -y ros-noetic-gazebo-ros-pkgs \
# ros-noetic-gazebo-ros \
# ros-noetic-gazebo-plugins && \
# curl -sSL http://get.gazebosim.org | sh

RUN echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc

RUN mkdir /workspace

ENTRYPOINT [ "/bin/bash", "-l", "-c" ]
42 changes: 42 additions & 0 deletions docker/Dockerfile.main.l4t-35.4.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
FROM dustynv/ros:noetic-desktop-l4t-r35.4.1 as base
LABEL maintainer="RoBorregos <[email protected]>"
# Install dependencies.
# Install dependencies.
RUN apt-get update -qq && apt-get install -y build-essential \
ffmpeg libsm6 libxext6 autoconf libtool mesa-utils \
terminator nano git wget curl iputils-ping \
libcanberra-gtk-module libcanberra-gtk3-module \
ros-dev-tools ros-noetic-teleop-twist-keyboard

# New stage for each feature added
############################################
# USER CONFIGURATION
############################################
FROM base as user

ARG USERNAME=ros
ARG USER_UID=1000
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 sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\
&& chmod 0440 /etc/sudoers.d/$USERNAME \
&& rm -rf /var/lib/apt/lists/*

# Set up autocompletion for user
RUN apt-get update && apt-get install -y git-core bash-completion \
&& echo "if [ -f /opt/ros/${ROS_DISTRO}/setup.bash ]; then source /opt/ros/${ROS_DISTRO}/setup.bash; fi" >> /home/$USERNAME/.bashrc \
&& echo "if [ -f /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash ]; then source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash; fi" >> /home/$USERNAME/.bashrc \
&& rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND=

RUN echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc

#RUN mkdir /workspace

ENTRYPOINT [ "/bin/bash", "-l", "-c" ]
2 changes: 1 addition & 1 deletion docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## Build images

Inside the `docker` folder in each module, there are different docker images. The convention for the naming of the **images** chosen is `home/feature:version`. Also, the `Dockerfile` should be named according to the feature and version.
Inside the `docker` folder in each module, there are different docker images. The convention for the naming of the **images** chosen is `home:area-version`, where version contains the platform used: `cpu`, `cuda` or `l4t-version`. Also, the `Dockerfile` should be named according to the feature and version.

Current images available:
- Noetic base full
Expand Down
Loading

0 comments on commit b957870

Please sign in to comment.