osrf / docker_images

A repository to hold definitions of docker images maintained by OSRF
Apache License 2.0
575 stars 172 forks source link

Can't access to any ROS commands inside container #754

Closed FurkanEdizkan closed 5 months ago

FurkanEdizkan commented 5 months ago

Hello I have been trying to create an docker container using noetic-ros-core, however I want to update the cmake package so I used the DockerFile I have written below, I can access to roscore and see topic from local with network: host option with docker-compose however I can't seem to access any ROS related function with docker compose.

How does docker-compose and docker compose difference effect my container

ENV TZ=Europe/Istanbul ENV DEBIAN_FRONTEND=noninteractive ENV ROS_DISTRO noetic ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8

Update and install basic dependencies

RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y ca-certificates build-essential libssl-dev wget apt-utils

Remove existing cmake if it is installed

RUN apt-get remove -y cmake

Download, extract, and install cmake 3.29.3

RUN wget https://github.com/Kitware/CMake/releases/download/v3.29.3/cmake-3.29.3.tar.gz && \ tar -zxvf cmake-3.29.3.tar.gz && \ cd cmake-3.29.3 && \ ./bootstrap && \ make && \ make install && \ cd .. && \ rm -rf cmake-3.29.3 cmake-3.29.3.tar.gz

Check the cmake version

RUN cmake --version

Install additional dependencies

RUN apt-get install -y git curl software-properties-common \ unzip apt-transport-https ca-certificates \ gnupg lsb-release wget ssh-client python3-netifaces \ usbutils && \ rm -rf /var/lib/apt/lists/*

COPY ./start.sh / RUN chmod +x /start.sh

RUN rosversion -d RUN mkdir src

RUN chmod +x ros_entrypoint.sh

TODO docker-compose working however docker compose is not working

- docker-compose.yaml
``` bash
services:
  amr:
    build:
        context: .
        dockerfile: DockerFile
    volumes:
      - .:/app
    network_mode: host
    ports:
      - "11311:11311"
    environment:
      - TZ=Europe/Istanbul
      - DEBIAN_FRONTEND=noninteractive
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    command: ./start.sh
ruffsl commented 5 months ago

I'm assuming that you're start script is somehow sourcing /opt/ros/noetic/setup.sh before attempting to run any ros commands?

FurkanEdizkan commented 5 months ago

Yes I source the ROS , I tried to source it from DockerFile but i didn't work either so I moved into start.sh

ruffsl commented 5 months ago

I tried to source it from DockerFile

Each RUN directive in a Dockerfile runs from it's own exec session, i.e. changes to the internal shell environment to not persists across RUN directives, only the file system changes that manifest as image layers. You would have to . /opt/ros/noetic/setup.sh && ... before using any ROS command in a Dockerfile.

FurkanEdizkan commented 5 months ago

I am not calling or starting any command inside DockerFile, I was calling it inside docker-compose command as start.sh. Inside start.sh I have source and running roscore

start.sh

#!/bin/bash

export ROS_MASTER_URI=http://$(hostname --ip-address):11311
export ROS_HOSTNAME=$(hostname --ip-address)
source /opt/ros/noetic/setup.sh
bash

exit_with_error() {
    echo "Error ($1): $2"
    exit $1
}

# Trap the EXIT signal to prevent immediate exit
trap 'exit_with_error $? "Script encountered an error"' EXIT

cmake --version
python3 --version
rosversion -d

roscore

# Keep the script running to prevent container exit
# tail -f /dev/null

--- Edit 1 --- When I run docker compose up --build I get

...
 => amr  8/11] RUN chmod +x /start.sh                                                                                                                             0.2s
 => [amr  9/11] RUN rosversion -d                                                                                                                                  0.3s
 => [amr 10/11] RUN mkdir src                                                                                                                                      0.1s
 => [amr 11/11] RUN chmod +x ros_entrypoint.sh                                                                                                                     0.2s
 => [amr] exporting to image                                                                                                                                       0.1s
 => => exporting layers                                                                                                                                            0.1s
 => => naming to docker.io/library/amr-amr                                                                                                                         0.0s
[+] Running 2/1
 ✔ Container amr-amr-1                                            Created                                                                                          0.1s 
 ! amr Published ports are discarded when using host network mode                                                                                                  0.0s 
Attaching to amr-1
amr-1  | /ros_entrypoint.sh: line 5: /opt/ros/noetic/setup.bash: No such file or directory
amr-1 exited with code 

--- Edit 2 --- When I use roslaunch inside DockerFile and remove command section from docker-compose.yaml roslaunch works, however docker-compose file doesn't give same error

...
Attaching to amr-1
amr-1  | /ros_entrypoint.sh: line 5: /opt/ros/noetic/setup.bash: No such file or directory
amr-1 exited with code 1
mikaelarguedas commented 5 months ago

Do you have the console output of your removal of cmake ?

Does't this result in uninstalling all ros packages ? (including the package installing /opt/ros/noetic/setup.bash)

FurkanEdizkan commented 5 months ago

I don't have it, I can run it again and print however, when I changed last lines of DockerFile with

# install ros package
RUN apt-get update && apt-get install -y \
      ros-${ROS_DISTRO}-ros-tutorials \
      ros-${ROS_DISTRO}-common-tutorials && \
    rm -rf /var/lib/apt/lists/*

# launch ros package
CMD ["roslaunch", "roscpp_tutorials", "talker_listener.launch"]

and remove command section from docker-compose.yaml

docker compose up --build works and ros publishes, I can't listen it from host machine however it is probably export issue on my end but it works. So I don't think/know if it is about me updating the cmake package

Edit 1:

I moved the command inside docker-compose.yaml

services:
  amr:
    build:
        context: .
        dockerfile: DockerFile
    volumes:
      - .:/app
    network_mode: host
    ports:
      - "11311:11311"
    environment:
      - TZ=Europe/Istanbul
      - DEBIAN_FRONTEND=noninteractive
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    command: ["roslaunch", "roscpp_tutorials", "talker_listener.launch"]

and it also worked and laucnhed the roslaunch

Edit 2:

I moved the roslaunch inside ./start.sh and called command: from docker-compose.yaml

services:
  amr:
    build:
        context: .
        dockerfile: DockerFile
    volumes:
      - .:/app
    network_mode: host
    ports:
      - "11311:11311"
    environment:
      - TZ=Europe/Istanbul
      - DEBIAN_FRONTEND=noninteractive
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    command: ["./start.sh"]
#!/bin/bash

export ROS_MASTER_URI=http://$(hostname --ip-address):11311
export ROS_HOSTNAME=$(hostname --ip-address)

echo $ROS_MASTER_URI
echo $ROS_HOSTNAME

# exit_with_error() {
#     echo "Error ($1): $2"
#     exit $1
# }

# # Trap the EXIT signal to prevent immediate exit
# trap 'exit_with_error $? "Script encountered an error"' EXIT

source /opt/ros/noetic/setup.sh

cmake --version
python3 --version
rosversion -d

roslaunch roscpp_tutorials talker_listener.launch

# roscore

# Keep the script running to prevent container exit
# tail -f /dev/null

and it also worked, however I can't seem to run roscore from anywhere?

Edit 3: Or I can't seem to see any topic from local machine even thought I have give network = host

mikaelarguedas commented 5 months ago

So I don't think/know if it is about me updating the cmake package

It seems like there are multiple issues at hand here.

I recommand you to start with a blanket ros-core image, and build your way up until you encounter issues. So far in your setup several things are surprising:

For example you can start with:

FROM ros:noetic-ros-core

RUN apt-get update && apt-get install -y \
      ros-${ROS_DISTRO}-roscpp-tutorials \
    && rm -rf /var/lib/apt/lists/*

docker-compose.yaml

services:
  testros:
    build:
        context: .
        dockerfile: Dockerfile
    image: testros:latest
    network_mode: "host"
    command: ["roslaunch", "roscpp_tutorials", "talker_listener.launch"]

Shell 1:

docker compose up --build

Shell 2:

rostopic echo /chatter

Once this is working as intended you can add complexity to your setup

FurkanEdizkan commented 5 months ago

Now ROS is working however still can't seem to listen topics from local machine. Also I need to update cmake to a upper version, so I need to use

# Remove existing cmake if it is installed
RUN apt-get remove -y cmake

# Download, extract, and install cmake 3.29.3
RUN wget https://github.com/Kitware/CMake/releases/download/v3.29.3/cmake-3.29.3.tar.gz && \
    tar -zxvf cmake-3.29.3.tar.gz && \
    cd cmake-3.29.3 && \
    ./bootstrap && \
    make && \
    make install && \
    cd .. && \
    rm -rf cmake-3.29.3 cmake-3.29.3.tar.gz

I checked to ros-core-noetic image it starts from ubuntu, is it more wise to just use ubuntu image then remove->update cmake then install ROS and all other related packages?

gavanderhoorn commented 5 months ago

CMake is also distributed via PyPI: project/cmake.

That doesn't require you to remove the existing install.

(I would not normally do this 'in production', but for a Docker image it could be acceptable)

FurkanEdizkan commented 5 months ago

I will also use realsence and other packages, and their newer versions required cmake version higher than what comes with ubuntu20.04, so I needed it to be updated

gavanderhoorn commented 5 months ago

Unless I'm misunderstanding you, the pip install should let you do that.

FurkanEdizkan commented 5 months ago

I will try to update CMake from pip in DockerFile

FurkanEdizkan commented 5 months ago

It really worked, thank you @gavanderhoorn @mikaelarguedas @ruffsl

The problem really was me removing the CMake to update it, just installing with RUN pip3 install cmake==3.29.5 solved the problem.

...
amr-1  | cmake version 3.29.5
amr-1  | 
amr-1  | CMake suite maintained and supported by Kitware (kitware.com/cmake).
amr-1  | Python 3.8.10
amr-1  | noetic
amr-1  | [ INFO] [1718102861.170382964]: I heard: [hello world 4]
amr-1  | [ INFO] [1718102861.270023560]: I heard: [hello world 5]
amr-1  | [ INFO] [1718102861.370116924]: I heard: [hello world 6]
...