Docker
Simple introduction about docker
Following tutorial: link
Official description: Docker provides the ability to package and run an application in a loosely isolated environment called a container. The isolation and security lets you run many containers simultaneously on a given host. Containers are lightweight and contain everything needed to run the application, so you don't need to rely on what's installed on the host.
Cited from "What is a container"
Imagine you're developing a killer web app that has three main components - a React frontend, a Python API, and a PostgreSQL database. If you wanted to work on this project, you'd have to install Node, Python, and PostgreSQL. How do you make sure you have the same versions as the other developers on your team? Or your CI/CD system? Or what's used in production? How do you ensure the version of Python (or Node or the database) your app needs isn't affected by what's already on your machine? How do you manage potential conflicts? Enter containers! What is a container? Simply put, containers are isolated processes for each of your app's components. Each component - the frontend React app, the Python API engine, and the database - runs in its own isolated environment, completely isolated from everything else on your machine. Here's what makes them awesome. Containers are: Self-contained. Each container has everything it needs to function with no reliance on any pre-installed dependencies on the host machine. Isolated. Since containers are run in isolation, they have minimal influence on the host and other containers, increasing the security of your applications. Independent. Each container is independently managed. Deleting one container won't affect any others. Portable. Containers can run anywhere! The container that runs on your development machine will work the same way in a data center or anywhere in the cloud!
Start and run multi-container with docker-compose.yml
docker compose up
Command
The command docker compose up
is used to start and run multi-container Docker applications defined in a docker-compose.yml
file.
What Does docker compose up
Do?
- Reads the
docker-compose.yml
file to determine which services (containers) need to be started. - Builds images if they don’t already exist.
- Creates and starts containers, networks, and volumes as defined in the file.
- Attaches to container logs, displaying output from all services in the terminal.
Basic Usage
To start all services defined in the docker-compose.yml
file:
Bash | |
---|---|
1 |
|
Common Options
Command | Description |
---|---|
docker compose up -d |
Run containers in the background (detached mode). |
docker compose up --build |
Rebuild the images before starting containers. |
docker compose up --force-recreate |
Force recreate containers even if they already exist. |
docker compose up <service_name> |
Start only a specific service from the docker-compose.yml file. |
Stopping the Services
To stop and remove all running containers:
Bash | |
---|---|
1 |
|
Running Multiple Docker Containers with Different ROS Versions
1. Running Multiple Docker Containers with Different ROS Versions
You can run multiple containers with different ROS versions using separate Docker images. Example:
Bash | |
---|---|
1 2 |
|
2. Sharing ROS Topics Between Containers
By default, containers are isolated, so ROS topics won't be shared unless you configure the network properly. Here’s how you can make topics available across containers:
ROS 1: Using a Shared ROS Master
For ROS1 (e.g., Noetic), you need to:
- Run a ROS Master in one container:
Bash 1
docker run -it --rm --network=host ros:noetic roscore
- Start other ROS1 containers and connect to the master:
Bash 1 2
docker run -it --rm --network=host ros:noetic bash export ROS_MASTER_URI=http://localhost:11311
- Setting
--network=host
allows all containers to share the same ROS network. - Alternatively, use a custom bridge network and explicitly set
ROS_MASTER_URI
to the master's IP.
ROS 2: Using DDS for Communication
ROS2 (e.g., Foxy) uses DDS (Data Distribution Service), which supports direct discovery. To allow inter-container communication:
- Use the same network (e.g.,
--network=host
or a custom bridge network):
Bash 1
docker run -it --rm --network=host ros:foxy ros2 run demo_nodes_py talker
- Ensure all containers have the same ROS_DOMAIN_ID:
Bash 1
export =42 # Set this in all containers
If running ROS1 and ROS2 together, you will need a ROS1-ROS2 bridge to translate topics between them.
3. Best Networking Practices
- Use
--network=host
for the simplest setup (but not ideal for security in production). - Create a Docker bridge network for better control:
Bash 1 2
docker network create ros_net docker run -it --rm --network=ros_net ros:noetic
- Use
ROS_MASTER_URI
(ROS1) or DDS settings (ROS2) to ensure proper topic sharing.
Example tutorial of using ROS2, Docker, SSH
Summary: Running ROS2 hello_world node inside docker container on InDro robot
SSH connection
Bash | |
---|---|
1 |
|
ROS2 workspace and package creation (ROS2 basic operations)
Step1: Initialize the ROS2 workspace and package
Bash | |
---|---|
1 2 3 4 5 6 7 8 |
|
Step2: Write the source code for the hello_indro node
Bash | |
---|---|
1 2 |
|
Python | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Step3: Make the script executable
Bash | |
---|---|
1 |
|
Step4: Edit the setup.py
file to modify the entry_points
Bash | |
---|---|
1 |
|
Python | |
---|---|
1 2 3 4 5 |
|
Step4: Build the ROS2 package and Source the environmental variable
Bash | |
---|---|
1 2 3 4 5 6 |
|
Docker Container Setup
Step1: Create the Dockerfile
Bash | |
---|---|
1 2 |
|
Docker | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Step2: Build the Docker image
Bash | |
---|---|
1 |
|
Run the hello_indro Node in Docker Container
Bash | |
---|---|
1 |
|
Debug & Test
Check the Docker container information
Bash | |
---|---|
1 2 3 4 5 6 7 |
|
Run a Docker container with an interactive shell:
Bash | |
---|---|
1 |
|
Rebuild the ROS2 package after modification
Bash | |
---|---|
1 |
|
Rebuild the Docker image
Bash | |
---|---|
1 2 |
|