From 9193d716c13c794e77d2e99a43f27af5e0874d70 Mon Sep 17 00:00:00 2001 From: Bhaswanth Ayapilla Date: Sat, 26 Apr 2025 17:36:14 -0400 Subject: [PATCH] add Team I docker for robotics wiki entry --- _data/navigation.yml | 2 + wiki/tools/docker-for-robotics.md | 506 ++++++++++++++++++++++++++++++ 2 files changed, 508 insertions(+) create mode 100644 wiki/tools/docker-for-robotics.md diff --git a/_data/navigation.yml b/_data/navigation.yml index 6600d2a4..c73e35bf 100644 --- a/_data/navigation.yml +++ b/_data/navigation.yml @@ -340,6 +340,8 @@ wiki: url: /wiki/tools/code-editors-Introduction-to-vs-code-and-vim/ - title: Qtcreator UI development with ROS url: /wiki/tools/Qtcreator-ros/ + - title: Docker for Robotics + url: /wiki/tools/docker-for-robotics/ - title: Datasets url: /wiki/datasets/ children: diff --git a/wiki/tools/docker-for-robotics.md b/wiki/tools/docker-for-robotics.md new file mode 100644 index 00000000..1ad158ac --- /dev/null +++ b/wiki/tools/docker-for-robotics.md @@ -0,0 +1,506 @@ +--- +date: 2025-04-25 # YYYY-MM-DD +title: Docker for Robotics +--- + +# Docker Overview + +Docker is a tool that helps you create, share, and run applications in containers. Containers are small, lightweight packages that include everything your application needs, like the code, libraries, and settings. They are faster and use fewer resources compared to virtual machines (VMs). + +**Difference Between Containers and Virtual Machines:** + +- Virtual Machines (VMs): Full operating systems running on top of a hypervisor. They are resource-heavy and slow to start. +- Docker Containers: Share the host OS kernel, making them faster, more lightweight, and more resource-efficient. + +**Key components:** + +- Images: Think of an image like a recipe. It tells Docker what to include in the container (software, libraries, etc.). +- Containers: These are the actual "live" versions of the image. It’s like cooking from the recipe — your container is the meal ready to eat. +- Dockerfile: A script that defines how an image is built, including base images, commands, and configurations. +- Volumes: Persistent storage that containers can use to save data. +- Docker Hub: A cloud-based repository where pre-built Docker images are shared. + +# Installation + +[Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/) + +[Install docker compose plugin](https://docs.docker.com/compose/install/linux/#install-the-plugin-manually) + +# Docker Commands + +## Images + +- Build an image from a Dockerfile: + + ```bash + $ docker build -t + ``` + +- Pull an image from a Docker Hub: + + ```bash + $ docker image pull : + ``` + +- Search Hub for an image: + + ```bash + $ docker image search + ``` + +- List local images: + + ```bash + $ docker image ls + $ docker images + ``` + +- Delete an image: + + ```bash + $ docker image rm + $ docker rmi + ``` + +- Remove all unused images: + + ```bash + $ docker image prune + ``` + + +## Containers + +- Create and run a container from an image, with a custom name: + + ```bash + $ docker run --name + ``` + +- Run a container with terminal: + + ```bash + $ docker run -it + ``` + +- Start or stop an existing container: + + ```bash + $ docker start|stop (or ) + ``` + +- Start an existing container with terminal: + + ```bash + $ docker start -i + ``` + +- List running containers: + + ```bash + $ docker container ls + $ docker ps + ``` + +- List all containers (even the stopped ones): + + ```bash + $ docker container ls -a + $ docker ps -a + ``` + +- Remove a stopped container: + + ```bash + $ docker rm + ``` + +- Remove all available containers: + + ```bash + $ docker container prune + ``` + +- Open terminal inside a running container: + + ```bash + $ docker container exec -it /bin/bash + ``` + + For any commands within a running container: + + ```bash + $ docker container exec -it + ``` + + +### Working with Volumes + +- Mount Host Directory to Container: This is how we can make a directory on host available inside the container + +```bash +$ docker run -it -v : +``` + +```bash +$ docker run -it --network=host --ipc=host -v : +``` + +Any files created in a container in a shared volume will be locked — can be accessed only by the root. + +**Note:** `docker run` always creates a new container. We lose any changes we make to the environment every time we `run` the container. + +## Setting up a Dockerfile + +The `Dockerfile` contains the steps for creating an image. It typically starts with a base image and includes commands for installing software, setting environment variables, and defining the container’s entrypoint. + +```docker +# FROM +FROM osrf/ros:humble-desktop-full + +# Commands to perform on base image +RUN apt-get -y update \ + && apt-get -y install some_package \ + && git clone https://github.com/some_user/some_repository some_repo \ + && cd some_repo \ + && mkdir build \ + && cd build \ + && cmake .. \ + && make -j$(nproc) \ + && make install \ + && rm -rf /var/lib/apt/lists/* + +# Install additional packages +RUN apt-get update && apt-get install -y \ + python3-pip \ + ros-humble-turtlebot3-simulations + +# Set up workspace +ENV WS_DIR="/root/ros2_ws" +WORKDIR ${WS_DIR} +RUN /bin/bash -c "source /opt/ros/humble/setup.bash && colcon build" + +# Default command +CMD ["/bin/bash"] + +# COPY +COPY config/ site_config/ + +# Define the script that should be launched upon start of the container +ENTRYPOINT ["/root/ros2_ws/src/my_script.sh"] +``` + +- All commands run in the docker container will run as `root`. +- The `COPY` command assumes paths are relative to the build context specified in the `docker-compose.yml` or the `docker build` command. +- To build and run the Docker image, go into the directory which will be the new image + +```bash +$ docker image build -t +$ docker run -it +``` + +## Entrypoint Scripts + +Entrypoint scripts automate container setup at runtime. It runs every time the container is brought up. + +- Create a new file called `entrypoint.sh` inside the directory. + +```bash +#!/bin/bash +source /opt/ros/humble/setup.bash +exec "$@" +``` + +- Add it to the `Dockerfile` + +```docker +COPY entrypoint.sh /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] +``` + +## GUI in Docker + +```bash +$ docker run -it --network=host --ipc=host -v : -v /tmp/.X11-unix:/tmp/.X11-unix:rw --env=DISPLAY +``` + +# Docker Compose + +Docker Compose simplifies multi-container applications by allowing you to define and manage them through a YAML file (`docker-compose.yml`). + +For newer versions (Docker v2.0 and later), use `docker compose` instead of `docker-compose`. + +## Basic Commands + +- Start and run all services defined in the `docker-compose.yml` file: + +```bash +$ docker compose up +``` + +- Start services in detached mode (background): + +```bash +$ docker compose up -d +``` + +- Stop all running services: + +```bash +$ docker compose stop +``` + +- Stop and remove all services, networks, and volumes: + +```bash +$ docker compose down +``` + +- Restart all services: + +```bash +$ docker compose restart +``` + +## Configuration Management + +- Validate the `docker-compose.yml` file: + +```bash +$ docker compose config +``` + +- View the service logs (real-time streaming): + +```bash +$ docker compose logs +``` + +- View logs of a specific service: + +```bash +$ docker compose logs +``` + +- Build or rebuild services + +```bash +$ docker compose build +``` + +- Build a specific service: + +```bash +$ docker compose build +``` + +- Pull service images defined in the `docker-compose.yml` file: + +```bash +$ docker compose pull +``` + +## Service Management + +A service represents a single containerized application or component in a multi-container setup. Each service corresponds to a container, and the docker-compose.yml file is used to define the configuration for these services. + +- Start a specific service + +```bash +$ docker compose up +``` + +- Stop a specific service: + +```bash +$ docker compose stop +``` + +- Remove stopped service containers: + +```bash +$ docker compose rm +``` + +- Remove a specific service container: + +```bash +$ docker compose rm +``` + +## Network and Volume Management + +- View networks created by Docker Compose: + +```bash +$ docker network ls +``` + +- View volumes created by Docker Compose: + +```bash +$ docker volume ls +``` + +- Remove unused networks: + +```bash +$ docker network prune +``` + +- Remove unused volumes: + +```bash +$ docker volume prune +``` + +## **Writing and launching a Docker-Compose file** + +Example `docker-compose.yml` for a ROS 2 project: + +```docker +version: '3.8' +services: + ros-master: + image: osrf/ros:humble-ros-core + container_name: ros-master + networks: + - ros-network + + turtlebot-sim: + image: osrf/ros:humble-desktop + container_name: turtlebot-sim + depends_on: + - ros-master + networks: + - ros-network + +networks: + ros-network: + driver: bridge +``` + +After having created both a `Dockerfile` as well as a `docker-compose.yml` you can launch them with: + +```bash +$ docker compose -f docker-compose.yml build +$ docker compose -f docker-compose.yml up +``` + +where with the option `-f` a Docker-Compose file with a different filename can be provided. If not given it will default to `docker-compose.yml`. + +More general `docker-compose.yml`: + +```docker +version: "3.9" +services: + some_service: # Name of the particular service (Equivalent to the Docker --name option) + build: # Use Dockerfile to build image + context: . # The folder that should be used as a reference for the Dockerfile and mounting volumes + dockerfile: Dockerfile # The name of the Dockerfile + container_name: some_container + stdin_open: true # Equivalent to the Docker -i option + tty: true # Equivalent to the Docker docker run -t option + volumes: + - /a_folder_on_the_host:/a_folder_inside_the_container # Source folder on host : Destination folder inside the container + another_service: + image: ubuntu/20.04 # Use a Docker image from Dockerhub + container_name: another_container + volumes: + - /another_folder_on_the_host:/another_folder_inside_the_container +volumes: + - ../yet_another_folder_on_host:/a_folder_inside_both_containers # Another folder to be accessed by both images +``` + +If instead you wanted only to run a particular service you could do so with: + +```bash +$ docker compose -f docker-compose.yml run my_service +``` + +Then similar to the previous section, we can connect to the container from another console with + +```bash +$ docker compose exec sh +``` + +where `` is given by the name specified in the `docker-compose.yml` file and `sh` stands for the type of comand to be execute, in this case we open a `shell`. + +# Docker Registry + +- Build image locally: + +```bash +$ docker compose build +``` + +- Tag the resulting image for Docker Hub: + +```bash +$ docker tag /: +``` + +- Push the image to Docker Hub: + +```bash +$ docker push /: +``` + +In case you're not logged in, use + +```bash +$ docker login -u +``` + +And then enter the password. + +It is necessary to include your Docker Hub username in the tag. + + +# Building Docker Images for Multiple Architectures + +- Ensure `qemu` emulation is enabled: You need to have `qemu-user-static` installed and properly configured for cross-platform builds. + +```bash +$ sudo apt-get install -y qemu-user-static +$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes +``` + +This ensures that the `qemu` emulator is registered for the required architectures. + +When building or running Docker images for a different architecture: + +1. Build Process: QEMU emulates the target architecture (e.g., `arm64`) on the host (e.g., `amd64`), enabling you to compile binaries and packages for the target system. +2. Run Process: QEMU interprets `arm64` instructions so that the container can run on an `amd64` host without errors. + +- Setup `buildx` + +```bash +$ docker buildx create --name multiarch --use +$ docker buildx inspect --bootstrap +``` + +- Tag the image that you want to push + +```bash +$ docker tag /: +``` + +- Build the multi-arch image + +```bash +$ docker buildx build --platform linux/amd64,linux/arm64/v8 \ + -t your-dockerhub-username/your-image-name:tag \ + --push \ + -f /path/to/Dockerfile /path/to/context +``` + +- The image will be pushed to Docker Hub + + + +# Additional Resources + +- [Docker for Development](https://docs.nav2.org/tutorials/docs/docker_dev.html) +- [Docker for Robotics](https://github.com/2b-t/docker-for-robotics/tree/main) +- [YouTube](https://youtube.com/playlist?list=PLunhqkrRNRhaqt0UfFxxC_oj7jscss2qe&si=j5NCJxazjTFhSNZ3) \ No newline at end of file