Skip to content

tutorials vrx_docker_scripted

M1chaelM edited this page Mar 25, 2022 · 15 revisions

Option 2: Automated Image Creation using a Dockerfile

In this tutorial we automate the entire process of creating the competitor image using a script called a Dockerfile.

  • This is one of two options for building a competitor image.
  • The first option is described here.
  • The primary advantage of this approach is that it is self-documenting and easily reproducible.

Build a Working Image

Follow the steps below to get a minimal version of a competitor image up and running:

Step 1: Create your Dockerfile

  • Create a directory to store your Dockerfile and any other files needed for your image.

    mkdir ~/my_vrx_docker; cd ~/my_vrx_docker
    
  • Create a file called Dockerfile, open it in a text editor, and copy in the following:

    # This is an auto generated Dockerfile for ros:ros-base
    # generated from docker_images/create_ros_image.Dockerfile.em
    FROM ros:noetic-ros-base
    
    # Install required utilities
    RUN apt update \ 
    && apt install -y --no-install-recommends \
          build-essential \
          dirmngr \
          git \
          gnupg2 \
          python3-rosdep \
          python3-rosinstall \
          python3-vcstools \
    

&& rm -rf /var/lib/apt/lists/*

Install ROS packages

RUN apt update
&& apt install -y --no-install-recommends
ros-noetic-geographic-msgs
&& rm -rf /var/lib/apt/lists/*

Copy over script to Docker container

COPY ./run_my_system.bash /

Use your ros_entrypoint

COPY ./ros_entrypoint.sh /

This script does the following:
* The `FROM` command tells Docker to begin from the `ros:noetic-ros-base` image.
* The `RUN` command executes arbitrary commands as if running them on the command line. In this case, they execute `apt` to install utilities and ROS packages. We don't actually need these packages yet. They are included as an examples of packages that might be useful later. 
  * Note that a common pattern for `RUN` commands is to chain sequences of commands together using `&&` so each command is only run if the previous command succeeds. The reason for grouping commands together in this way is that environmental variables do not persist from one line of the `Dockerfile` to the next. Only changes that would be written to disk persist.
  * Conversely, we clear out temporary files after each call to `apt` to avoid written unneeded files to the disk and cluttering the image.
* The `COPY` command copies files from the host file system into the specified location in the docker image. In this case, the two files referenced do not yet exist. We will create them in the next step.

### Step 2: Create scripts locally
By default, the `ros:noetic-ros-base` image we started from is configured to look for and execute the `ros_entrypoint.sh` script when it is run. We will create this script and use it to call a custom script that will control our WAMV.
* First, use a text editor to create a file called `ros_entrypoint.sh` and copy the following text into the file:

#!/bin/bash set -e

setup ros environment

source "/opt/ros/$ROS_DISTRO/setup.bash"

/run_my_system.bash

* Run `chmod +x ros_entrypoint.sh` to make it executable.

* Now use a text editor to create a file called `run_my_system.sh` and copy the following text into the file:

#!/bin/bash

Create ros master if not already started

rostopic list > /dev/null 2>&1 retVal=$? if [ $retVal -ne 0 ]; then roscore & echo "Wait for 5s to allow rosmaster to start" sleep 5s else echo "rosmaster already setup" fi

Send forward command

RATE=1 CMD=2 echo "Sending forward command" rostopic pub /left_thrust_cmd std_msgs/Float32 -r ${RATE} -- ${CMD} & rostopic pub /right_thrust_cmd std_msgs/Float32 -r ${RATE} -- ${CMD}

* Run `chmod +x run_my_system.bash` to make it executable.

### Step 3: Build your image
We will now use the `docker build` command to create an image from the `Dockerfile`.
* First, set up some useful variables, substituting the appropriate values below:

USERNAME=<dockerhub_username> IMAGE_NAME=<name_your_image> TAG=<image_version>

* `USERNAME` must match the username of your Dockerhub account. 
* `IMAGE_NAME` should describe your image. It will be used to find your image locally and on Dockerhub.   
* `TAG` can be anything, but we recommend you use it to store version information.

* Build the image:

docker build --tag ${USERNAME}/${IMAGE_REPOSITORY_NAME}:${TAG}

* For example:

USERNAME=virtualrobotx IMAGE_NAME=vrx-competitor-example TAG=v2.2019 docker build --tag ${USERNAME}/${IMAGE_REPOSITORY_NAME}:${TAG}


### Step 4: Run your image
* Run `docker run <USERNAME>/<IMAGE_REPOSITORY_NAME>:<TAG>` This will create a container with the image you created in the previous step, and then run `/run_my_system.bash`.


### Step 5: Push your image to Dockerhub
* Run `docker login` and enter your credentials.
* Push your image: 

docker push ${USERNAME}/${IMAGE_NAME}:${TAG}

* You should be able to log onto your Dockerhub account at https://hub.docker.com and see your new repository. 

#### Optional: Make your repository private
* If you want to keep your repository private, you can click on your repository, then click Settings, then Make Private.
* To ensure we can access and evaluate your image, you can click Collaborators and add `virtualrobotx`.

|Back: [Option 2: Scripted](https://github.com/osrf/vrx/wiki/tutorials-vrx_docker_scripted) | |Top: [VRX Docker Image Overview](https://github.com/osrf/vrx/wiki/tutorials-vrx_competitor_image)|Next: [Minimal Working Examples](https://github.com/osrf/vrx/wiki/tutorials-vrx_docker_mwes)|
|:--|:-:|--:|  

Clone this wiki locally