Docker Basics - KSU-ART/tutorial-site GitHub Wiki

The Bare Minimum

Installation

  1. Windows/MAC: https://www.docker.com/products/docker-toolbox
  2. Ubuntu: https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/

Start an interactive container for catkin-build

docker run -i -t \
--name build0 ksuart/catkin-build:depends-ros /bin/bash

Start an interactive container for catkin-build with a shared folder

docker run -i -t \
-v "/c/Users/Documents:/root/Documents" \ # You can modify these directories; this is an example
--name build0 ksuart/catkin-build:depends-ros /bin/bash

Start an old container in interactive mode

docker start -i build0

Other Useful Commands

Enter an active docker container from new terminal

docker exec -i -t <container_name> /bin/bash

docker exec -i -t <container_id> /bin/bash

Exit a container

exit

Exit a container without killing it

CTRL-p and CTRL-q

View active containers

docker ps

View all containers

docker ps -a

View all containers and their sizes

docker ps -as

Remove a container permanently

docker rm <name>

docker rm <container_id>

Pull a specific image

(running a container will automatically pull the required image, so this is normally unnecessary)

docker pull ksuart/catkin-build

docker pull ksuart/catkin-build:depends-ros

View all images on device

docker images -a

Remove a specific image

docker rmi <image_id>

Advanced

catkin_make

# Set up variable for base container
echo "MY_ROS_IMAGE='ksuart/catkin-build'" >> ~/.bashrc

Add the following aliases to your ~/.bash_aliases:

# Clean catkin_make, removes build && devel
alias ccm='docker run --rm -itv ~/catkin_ws:/root/catkin_ws $MY_ROS_IMAGE\
           sh -c "cd /root/catkin_ws && mkdir src || : && rm -rf build/ devel/ && catkin_make"'
# Regular catkin_make
alias cm='docker run --rm -itv ~/catkin_ws:/root/catkin_ws $MY_ROS_IMAGE \
          sh -c "cd /root/catkin_ws && catkin_make"'
# full access to catkin env
alias env='docker run --rm -itv ~/catkin_ws:/root/catkin_ws -w="/root/catkin_ws/" $MY_ROS_IMAGE'

Run a ros system with docker containers

# Create a network for your docker containers:
docker network create skynet

Set up this in your ~/.bash_aliases:

# run roscore container
alias roscore='docker run -it --rm \
    --net skynet \
    --name master \
    ros:kinetic-ros-core \
    roscore'

Now, with custom containers for each node,

docker run -it --rm \
    --net skynet \
    --name $NODE_NAME \
    --env ROS_HOSTNAME=$NODE_NAME \
    --env ROS_MASTER_URI=http://master:11311 \
    --device=/dev/ttyUSB1:/dev/ttyACM0 \
    $NODE_IMAGE \
    rosrun $PACKAGE $NODE_NAME

Set up a containerized ros system across computers (swarm)

Open ports 2377, 7946, and 4789.

# Start a swarm
docker swarm init --advertise-addr=$HOSTIPADDRESS --listen-addr $HOSTIPADDRESS:2377
# Connect all systems to the swarm
docker swarm join --token $JOINTOKEN $HOSTIPADDRESS
  • $JOINTOKEN is the worker join-token provided as output by the docker swarm init
# Create an overlay network
docker network create --driver=overlay $NETWORKNAME
# View all swarm-nodes
docker node ls
# Add labels to distinguish between different nodes
docker node update --label-add $LABELNAME=$LABELVALUE $ID
  • $LABELNAME=$LABELVALUE example: type=robot and type=ground_station
  • $ID can be seen from output of docker node ls. HOSTNAME also works.
# run the roscore container on one of the machines
docker service create --name=master --network=$NETWORKNAME \
    --constraint node.labels.type=ground_station ros:kinetic-ros-core "roscore"
  • docker service logs --follow command will continue streaming the new output from the service’s STDOUT and STDERR
  • or use the above version of roscore.
# Run desired containers on each system
docker run -it --rm \
    --net $NETWORKNAME \
    --name $NODE_NAME \
    --env ROS_HOSTNAME=$NODE_NAME \
    --env ROS_MASTER_URI=http://master:11311 \
    --device=/dev/ttyUSB1:/dev/ttyACM0 \
    $NODE_IMAGE \
    rosrun $PACKAGE $NODE_NAME
  • cannot use docker services for this until --device support for services is added.
  • edit: may be able to access devices using volumes (--mount)?
⚠️ **GitHub.com Fallback** ⚠️