Docker Compose allows us to manage multiple containers with a single configuration file. A Docker network is automatically created so the containers can communicate with each other. The tool works from a yaml file named docker-compose.yml which contains the complete configuration of each container.
In the previous post, we created our container with a command line containing several parameters. These can be put into the docker-compose.yml file to simplify the process.
Starting with an empty directory, create a new file named docker-compose.yml with the following contents:
services:
sim:
image: ros_docker:latest
command: ros2 run turtlesim turtlesim_node
environment:
DISPLAY:
QT_X11_NO_MITSHM: 1
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix:rw
From a terminal in the jazzy folder, run the command:
docker compose up -d
This will create a new container, start it up and run the command to launch the turtlesim_node in the turtlesim package. The '-d' option runs the commands in the background, returning the terminal prompt to you (otherwise the terminal window is tied up until the node is terminated).
You should see the TurtleSim window open. Run the command docker ps to see what containers are running. You should see a new container was created named 'jazzy-sim-1'. This time instead of being randomly generated the container name has been taken from the folder name, and service name used. As it is the first instance, it is appended with '-1'.
If you close the TurtleSim window, the container will exit as the node it was running has terminated. If you run the 'docker compose up -d' command again it will restart the existing container, rather than creating a new one each time, compared to the 'docker run' command we used previously.
We can add more services to run additional containers and launch them as a group. Extend the docker-compose.yml file to contain the following:
services:
sim:
image: ros_docker:latest
command: ros2 run turtlesim turtlesim_node
environment:
DISPLAY:
QT_X11_NO_MITSHM: 1
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix:rw
dev-build:
image: ros_docker:latest
command: rqt
environment:
DISPLAY:
QT_X11_NO_MITSHM: 1
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix:rw
Now when you run 'docker compose up -d' you should see you have 2 containers, one named 'jazzy-sim-1' and a second named 'jazzy-dev-build-1' running the rqt tool. As these are automatically in the same docker network, the rqt tool can control the TurtleSim node as in the ROS Tutorials. If you close one of the tool windows (stopping its container) and run 'docker compose up -d' again, it will detect that one of the containers is already running, and just launch the one which is stopped.
As before, you can open an interactive shell in these containers, using the exec command:
docker exec -it jazzy-dev-build-1 bash
This allows us to set up the shell to source the ROS packages as before, by running the following command from the shell:
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
Now exit the shell, and use docker exec to start a new one. You should be able to run ROS2 commands from the shell now. Interestingly, it was not necessary to source the setup.bash script in the docker-compose.yml file to run the ROS2 commands there. I am not clear why it works, but it does so I'm happy with it.
Access to the file system of the Host
dev-build:
image: ros_docker:latest
command: rqt
environment:
DISPLAY:
QT_X11_NO_MITSHM: 1
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix:rw
- ~/ros2_ws:/ros2_ws
Stop the container (by closing the rqt tool window) and start it again by running the 'docker compose up -d' command. Now if you open a shell in the jazzy-dev-build-1 container, you should see a folder /ros2_ws which will be mapped to the folder ~/ros2_ws on the host. This should enable you to run the package building tutorials with the files being saved outside your container. So if your container is ever destroyed, the files are not lost when a new container is created by Docker Compose. Note that as we have changed our docker-compose.yml file, Docker Compose will detect the change and destroy the old container and recreate it. So once it starts up again, we will need to source our ROS2 packages again (just once if we put the command into the bash.rc file again).
No comments:
Post a Comment