Docker Grading Environment Guide

To grade your assignments, we use a class Docker image to compile, build, and run your code. The following sections explain how you might use this Docker image to ensure you see the same results we do. Additionally, the class Docker image contains TA demos of class projects. Setting up Docker locally will give you access to the demos independent of the department filesystem!

Docker Overview

From the Docker docs:

Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications.

For the purposes of this class, you can think of Docker as a virtual machine that contains a standardized build environment. By checking that your code builds and runs in this standardized environment, you can be sure that we can build and run your code as well.

Terminology

TermDescription
ImageA Docker image is a read-only template for creating a Docker container. An image is only the instructions for how to set up the environment. What is actually being run is a Docker container.
ContainerA Docker container is a mostly isolated environment in which you can, for instance, build and run applications.
VolumeA Docker volume is more or less a portion of your filesystem which can be accessed by a Docker container. Here, we will use it to share files between your host machine and your Docker container.

Gradescope

If you only want to check that your project compiles, each Gradescope assignment has an autograder setup that only checks if the project successfully compiles when you submit. This requires no local setup on your end!

Running Docker Locally

Verifying that your code compiles correctly in the Docker environment should be sufficient. However, if you really want to ensure that we are seeing the same graphical output that you're seeing, or you want access to the TA demos on your machine, you will need to setup Docker locally.

  1. Get Docker here.
  2. Pull our grading environment with docker pull anc2001/cs1230_env:latest.
    • If any of the steps below fail, try pulling the image again as it will receive periodic updates throughout the semester
  3. If you don't already have it, get python here
  4. Clone this repo for access to convenience scripts

The process of using the class environment involves first building the project into a Docker image, and then running that image as either a graphical session, or as an interactive session if you need to run things from the command line.

If you are on Windows, you must run these commands in Git Bash or Powershell.

Additionally, all filepaths must be specified with // (i.e. you must use these as your filepath separators). This includes the path to the source code SRC_PATH and the other filepaths present in the command. "Windows-specific versions" of some commands below are included in collapsible sections.

Convenience Scripts

Included in the repo you just cloned are two convenience python scripts build.py and run.py. These should abstract away many of the docker commands required to compile and run your code in our standardized environment. Example usage shown below.

Building and Running

First build the project. This command will take the source code at the path given, build it, and then write the necessary files to a docker image called qt_project by default.

python3 build.py -s /path/to/src
  • /path/to/src specifies the absolute path to your source code (remember to ensure the filepath uses // separators if you're on Windows).

Next run the project in a Docker container. This will run the previously built docker image qt_project in a docker container called qt_app

python3 run.py -e executable_name
  • executable_name specifies the name of the executable which will eventually be run. Note that for all CS 1230 assignments, the executable name is exactly the project name specified in the assignment's CMakeLists.txt (it is the first thing in the parentheses in project(...)).

Running TA Demo

Within the docker image are TA demos for each of the projects. These demos are available through the run.py script. Example usage is shown below.

python3 run.py --demo -e executable_name -i anc2001/cs1230_env:latest
  • executable_name is the name of the project you want to show. If the name has a min suffix, it will run the minimum working solution, and a max suffix will run an implementation with extra credit features implemented. The executable name options are
    • projects_2d_min
    • projects_2d_max

You may have noticed that the Ray and Realtime project demos are not yet available. TA demos of those projects will be available when their respective projects are released!

Script usage

Note that CONTAINER and IMAGE can be anything you want. We suggest keeping the defaults, but feel free to change them if you want.

usage: build.py [-h] -s SOURCE [-c CONTAINER] [-i IMAGE]

optional arguments:
  -h, --help            show this help message and exit
  -s SOURCE, --source SOURCE
                        absolute filepath to source code (required)
  -c CONTAINER, --container CONTAINER
                        name of temporary container (default qt_build)
  -i IMAGE, --image IMAGE
                        name of image (default qt_project)
usage: run.py [-h] [--mode MODE] [--demo] -e EXECUTABLE [-c CONTAINER] [-i IMAGE]

optional arguments:
  -h, --help            show this help message and exit
  --mode MODE           either graphical or cli
  --demo                Flag to specify running the TA demo
  -e EXECUTABLE, --executable EXECUTABLE
                        name of executable (required)
  -c CONTAINER, --container CONTAINER
                        name of container (default qt_app)
  -i IMAGE, --image IMAGE
                        name of image (default qt_project)

In Case of Failure: Alternative Method for Running Docker Locally

In case the convenience scripts fail, try the following steps to build and run your code in the standardized environment. The convenience scripts essentially run these commands for you, but in case of failure, working with Docker commands explicitly is more likely to be successful.

Building

To begin, we must define some environment variables for naming purposes. These follow the same naming requirements as the convenience scripts.

export SRC_PATH=/absolute-path/to/src \
  EXECUTABLE=executable_name \
  CONTAINER=qt_app \
  IMAGE=cs1230_qt_project

With these next commands, we'll actually build the project—this will take your source code, build it, and write that image to a docker image named IMAGE.

docker run \
    --name ${CONTAINER} \
    --platform=linux/amd64 \
    -v "${SRC_PATH}:/tmp/src" \
    anc2001/cs1230_env:latest \
    /opt/build_project.sh

docker image rm ${IMAGE}
docker commit ${CONTAINER} ${IMAGE}
docker container rm ${CONTAINER}
Windows Git Bash Version
docker run \
    --name ${CONTAINER} \
    --platform=linux/amd64 \
    -v "${SRC_PATH}://tmp//src" \
    anc2001/cs1230_env:latest \
    //opt//build_project.sh

docker image rm ${IMAGE}
docker commit ${CONTAINER} ${IMAGE}
docker container rm ${CONTAINER}
What do the above commands actually do?

--name specifies the name of the container

--platform specifies the architecture the docker container will run on

-v "${SRC_PATH}:/tmp/src" mounts a volume in the container. The files at SRC_PATH (the project source code) will be accessible at /tmp/src within the container

anc2001/cs1230_env:latest is the name of the Docker Image the container is based on

/opt/build_project.sh is the script the docker container will run upon starting

docker image rm ${IMAGE} - deletes the previous image at IMAGE

docker commit ${CONTAINER} ${IMAGE} - saves the container as permanent memory at IMAGE, otherwise the compiled executable will disappear after the container is removed

docker container rm ${CONTAINER} - Remove the container

Running

Graphical Output (Raster and Realtime projects)

This will run the previously build docker image (cs1230_qt_project) in a docker container and connect it to a graphical display accessible within any modern browser at http://localhost:6080:

docker run \
  --platform=linux/amd64 \
  -d \
  --name ${CONTAINER} \
  --env="APP=/tmp/build/${EXECUTABLE}" \
  -p 6080:6080 \
  ${IMAGE} \
  /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
Windows Git Bash Version
docker run \
  --platform=linux/amd64 \
  -d \
  --name ${CONTAINER} \
  --env="APP=//tmp//build//${EXECUTABLE}" \
  -p 6080:6080 \
  ${IMAGE} \
  //usr//bin//supervisord -c //etc//supervisor//supervisord.conf
What do the above commands actually do?

-d means the container runs in detached mode (i.e. in the background).

--env sets the environment variable APP inside the container. By default the APP environment variable is not set. If the APP environment variable points to an invalid path or is empty, no graphical output will show when connected to the localhost (the container will still run)

-p opens up a port at 6080 by default, you can change this if you really want by changing the first argument number.

/usr/bin/supervisord -c /etc/supervisor/supervisord.conf is the command to open up a graphical session and expose it at the corresponding port.

The application should now be available at http://localhost:6080

When you're done with the docker container you can run docker stop ${CONTAINER} and docker container rm ${CONTAINER}

Command Line (Ray projects)

This will open up the previously built image with an interactive terminal session that allows you to run the executable. Since the example is Ray, It will also mount a volume at RESULTS_PATH so that you can see the resulting images.

export RESULTS_PATH=/path/to/results

docker run \
  --rm \
  -it \
  --platform=linux/amd64 \
  -v "${RESULTS_PATH}:/tmp/results" \
  ${IMAGE} \
  /bin/bash
Windows Git Bash Version
export RESULTS_PATH=//path//to//results

docker run \
  --rm \
  -it \
  --platform=linux/amd64 \
  -v "${RESULTS_PATH}://tmp//results" \
  ${IMAGE} \
  //bin//bash
What do the above commands actually do?

-it specifies an interactive session

--rm will remove the container when exited

/bin/bash is the command to open up bash upon starting the container

Ray-specific: Make sure your .ini files point to an output image at /tmp/results so that you can see your images!

Running TA demos

If the python script fails when running the TA demo, try going through sections 4.1 - 4.2 again but with

  • IMAGE environment variable set to anc2001/cs1230_env:latest.
  • The docker run command for running the graphical application in 4.2.1 edited. Replace the value of APP with /demos/executable_name/build/executable_name_prefix. For example
--env="APP=/tmp/build/${EXECUTABLE}"
  ===>
--env="APP=/demos/projects_2d_min/build/projects_2d"