I have a docker container that has Webots and ROS2 installed. However, running webots
while inside the container returns bash: webots: command not found
. Why?
webots
(but no ROS2)Here's a container run from the Webots installation instructions that DOES successfully run webots
(but lacks ROS2 like I need):
$ xhost +local:root > /dev/null 2>&1 #so webots won't say unable to load Qt platform plugin "xcb"
$ docker run -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:rw cyberbotics/webots:R2021a-ubuntu20.04
webots
Here's my docker container which does NOT successfully run webots
, but instead says bash: webots: command not found
. However, it DOES successfully run webots_ros2
demos (I think the issue has to do with how I'm inheriting from two containers, because if I swap the order of my two ARG
and FROM
statements, webots
is found but ros2
is not. I'm not sure the solution though):
# inherit both the ROS2 and Webots containers
ARG BASE_IMAGE_WEBOTS=cyberbotics/webots:R2021a-ubuntu20.04
ARG IMAGE_ROS2=niurover/ros2_foxy:latest
FROM $BASE_IMAGE_WEBOTS AS base
FROM $IMAGE_ROS2 AS image_ros2
# resolve a missing dependency for webots demo
RUN apt-get update && apt-get install -y \
libxtst6 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Finally open a bash command to let the user interact
CMD ["/bin/bash"]
#! /bin/bash
CONTAINER_USER=$USER
CONTAINER_NAME=webots_ros2_foxy
USER_ID=$UID
IMAGE=niurover/webots_ros2_foxy:latest
if [ $(uname -r | sed -n 's/.*\( *Microsoft *\).*/\1/ip') ];
then
xhost +local:$CONTAINER_USER
xhost +local:root
fi
sudo docker run -it --rm \
--name $CONTAINER_NAME \
--user=$USER_ID\
--env="DISPLAY" \
--env="CONTAINER_NAME=$CONTAINER_NAME" \
--workdir="/home/$CONTAINER_USER" \
--volume="/home/$CONTAINER_USER:/home/$CONTAINER_USER" \
--volume="/etc/group:/etc/group:ro" \
--volume="/etc/passwd:/etc/passwd:ro" \
--volume="/etc/shadow:/etc/shadow:ro" \
--volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
$IMAGE bash\
if [ $(uname -r | sed -n 's/.*\( *Microsoft *\).*/\1/ip') ];
then
xhost -local:$CONTAINER_USER
xhost -local:root
fi
As you can see, both containers use cyberbotics/webots:R2021a-ubuntu20.04
, and the second container uses all of the options of the first container, but with some extras. Why does the first container run webots
successfully, while the second container can't find the command?
When you have multiple FROM
commands, you're not "inheriting" both of their contents into the same image - you're doing a multi-stage build. This allows you to COPY
from that stage specifying the --from
option. By default, the last stage in your Dockerfile will be the target (so, in your example, you're only actually using the ros2 image. The webots image is not actually being used there.
You have two options here:
COPY --from=base
This will probably be hard and finicky. You'll need to copy all dependencies; and if they're acquired through your package manager (apt-get), you'll leave dpkg's local database inconsistent.
Dockerfile
s and change their FROM
This will probably work fine as long as they both use the same base distribution. You can go into one of the project's repositories and grab their Dockerfile
, rebuilding it from the other image - just change, for example, cyberbotics/webots:R2021a-ubuntu20.04
's Dockerfile to have FROM niurover/ros2_foxy:latest
. It may require tinkering with the other commands there, though.