Skip to content

Docker Workflow Guide

This guide covers practical Docker operations for AirStack development. For concepts, see Key Concepts.

Quick Reference

# Start/stop
airstack up              # Start all services
airstack up robot-desktop        # Start only robot
airstack down            # Stop all services

# Manage
airstack status          # Show running containers
airstack connect robot   # Connect to container
airstack logs robot      # View logs

# Pull/build images
docker compose pull      # Pull from registry
docker compose build     # Build from scratch

Pull Images

To use the AirLab docker registry:

cd AirStack/
docker login airlab-docker.andrew.cmu.edu
## <Enter your andrew id (without @andrew.cmu.edu)>
## <Enter your andrew password>

## Pull the images in the docker compose file
docker compose pull

The available image tags are listed here.

Build Images

# Build all images from scratch
docker compose build

# Build specific service
docker compose build robot

Isaac Sim

Start a bash shell in the Isaac Sim container:

# if the isaac container is already running, execute a bash shell in it
airstack connect isaac-sim  # or equivalently: docker exec -it isaac-sim bash

Within the isaac-sim Docker container, the alias runapp launches Isaac Sim. The --path argument can be passed with a path to a .usd file to load a scene.

It can also be run in headless mode with ./runheadless.native.sh to stream to Omniverse Streaming Client or ./runheadless.webrtc.sh to stream to a web browser.

The container also has the isaacsim ROS2 package within that can be launched with ros2 launch isaacsim run_isaacsim.launch.py.

Robot

Start a bash shell in a robot container, e.g. for robot_1:

airstack connect robot  # or equivalently: docker exec -it airstack-robot-desktop-1 bash

To launch more than one robot, prepend with the NUM_ROBOTS=[NUM] environment variable, e.g. to launch 2 robots (along with the ground control station and Isaac Sim):

NUM_ROBOTS=2 airstack up
airstack connect robot-1  # to connect to robot 1
airstack connect robot-2  # to connect to robot 2

The previous docker compose up launches robot_bringup in a tmux session. To attach to the session within the docker container, e.g. to inspect output, run tmux a.

The following commands are available within the robot container:

# in robot docker
cws  # cleans workspace
bws  # builds workspace
bws --packages-select [your_packages] # builds only desired packages
sws  # sources workspace
ros2 launch robot_bringup robot.launch.xml  # top-level launch

These aliases are defined in AirStack/robot/.bashrc.

Each robot has ROS_DOMAIN_ID set to its ID number. ROBOT_NAME is set to robot_$ROS_DOMAIN_ID.

Ground Control Station

Currently the ground control station uses the same image as the robot container. This may change in the future.

Start a bash shell in a robot container:

airstack connect gcs  # or equivalently: docker exec -it gcs bash

The available aliases within the container are currently the same.

On the GCS ROS_DOMAIN_ID is set to 0.

SSH into Robots

The containers mimic the robots' onboard computers on the same network. Therefore we intend to interface with the robots through ssh.

The gcs and docker-robot-* containers are setup with ssh daemon, so you can ssh into the containers using the IP address.

You can get the IP address of each container by running the following command:

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [CONTAINER-NAME]

Then ssh in, for example:

The ssh password is airstack.

Automated Testing

To perform automated tests for the configured packages, please use the autotest service which extends the robot service with testing specific commands. Presently only takeoff_landing_planner is configured to be tested.

# On your development PC, do:

docker compose up autotest

This command will spin up a robot container, build the ROS2 workspace, source the workspace and run all the configured tests for the provided packages using colcon test. Excessive output log from the build process is presently piped away to preserve readability.

Docker Compose Variable Overrides

As mentioned above, the airstack CLI is a wrapper around Docker Compose. Therefore, it supports variable interpolation in the docker-compose.yaml file, allowing you to adjust project settings by modifying environment variables.

For example, to disable playing the simulation on startup, you can set the PLAY_SIM_ON_START variable to false:

PLAY_SIM_ON_START=false airstack up

To change the Isaac Sim scene:

ISAAC_SIM_SCENE=path/to/your_scene.usd airstack up

To disable autolaunching the stack and simply spawn idle docker containers (useful for debugging):

AUTOLAUNCH=false airstack up

A list of all available environment variables is in the default .env file in the project root directory, which allows specifying all the variables in one place. When no --env-file argument is passed to docker compose, it automatically uses this default .env file.

The default .env file is reproduced below:

# This is the main .env file for AirStack, which sets DOCKER COMPOSE VARIABLES FOR VARIABLE INTERPOLATION IN docker-compose.yaml.
# These variables do NOT get set within the robot container itself. For setting container environment variables, use env_file: attribute in docker-compose.yaml.
# Standard Usage: airstack --env-file .env up

# Warning: even though this file is organized into sections, all variables get propagated to all sub-level 
#  docker-compose files, so be careful about naming conflicts.

# =============== PROJECT ====================
# THESE VARIABLES ARE USED TO TAG THE DOCKER IMAGES.
# The name of the project. This is used as the repository name for the docker images, and also as part of the default image tag.
PROJECT_NAME="airstack"
# If you've run ./airstack.sh setup, then this will auto-generate from the git commit hash every time a change is made 
# to a Dockerfile or docker-compose.yaml file. Otherwise this can also be set explicitly to make a release version.
# auto-generated from git commit hash. `airstack version` will output this tag.
# auto-generated from git commit hash
DOCKER_IMAGE_TAG="0.17.0"
# Choose "dev" or "prebuilt". "dev" is for mounted code that must be built live. "prebuilt" is for built ros_ws baked into the image
DOCKER_IMAGE_BUILD_MODE="dev"  
# Where to push and pull images from. Can replace with your docker hub username if using docker hub.
PROJECT_DOCKER_REGISTRY="airlab-docker.andrew.cmu.edu/airstack"
# This is the default profile that docker compose will use if you just run `docker compose up` without specifying a profile. 
# It can be overridden with the --profile flag, or by setting the COMPOSE_PROFILES environment variable to a different value
#  before running `docker compose up`.
COMPOSE_PROFILES="desktop"  
# ============================================

# ================= Common ===================
AUTOLAUNCH="true"  # If false, the docker-compose will just spawn idle docker containers with no launch command.
NUM_ROBOTS="1"  # Number of robot containers to launch.
RECORD_BAGS="false"  # "true" or "false"

# ============== SIMULATION =====================
ISAAC_SIM_GUI="/isaac-sim/AirStack/simulation/isaac-sim/assets/scenes/simple_pegasus.scene.usd"
# Set to "true" to launch Isaac Sim using a standalone Python script instead of USD file
ISAAC_SIM_USE_STANDALONE="false" # "true" or "false"
# Script name (must be in /AirStack/simulation/isaac-sim/launch_scripts/)
ISAAC_SIM_SCRIPT_NAME="example_one_px4_pegasus_launch_script.py"
PLAY_SIM_ON_START="false"
# ===============================================

# ================= ROBOT =====================
ROBOT_NAME_MAP_CONFIG_FILE="default_robot_name_map.yaml"  # Determines how to set ROBOT_NAME and ROS_DOMAIN_ID. See robot/docker/robot_name_map/

URDF_FILE="robot_descriptions/iris/urdf/iris_with_sensors.pegasus.robot.urdf"  # 

# offboard API streaming out. this is so that ports don't conflict for multi-agent FCU communication. 
OFFBOARD_BASE_PORT=14540
ONBOARD_BASE_PORT=14580
# ===============================================

To override the default .env file, you can pass the --env-file argument with the syntax airstack --env-file [env_file] up (or docker compose --env-file [env_file] up -d).

Multiple --env-file arguments can be passed to compose overriding sets of variables.env files. All subsequent --env-file arguments override the previous ones, allowing you to layer configurations.