-
Notifications
You must be signed in to change notification settings - Fork 1
3. Development and Testing
Once a UCloud course has been created, the teacher is ready to start developing and testing the course. This is done using the template files that were copied into the course's folder when it was created.
The different template files in the course folder contain only the minimally required information and commands. As such, the bulk of the work of implementing a UCloud course for the teacher is to modify the Dockerfile and start_course.sh as required for their specific course.
The Dockerfile consists of a few general blocks and should be modified as necessary by the teacher.
The base image already includes:
- The default user which has
sudoprivileges - The
/homeand/workdirectories - Package managers needed to install software packages from terminal.
Below is an example of a Dockerfile which uses ubuntu as the base image, copied into the course folder upon course creation:
FROM dreg.cloud.sdu.dk/ucloud-apps/base-ubuntu:Nov2024
LABEL course="" \
author="" \
description=""
## Use bash instead of sh
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
USER 0
WORKDIR /home/$USER
USER ${USERID}
## Add entrypoint script
COPY --chown=$USER:$USER start_course.sh /usr/bin/start_course
RUN chmod 755 /usr/bin/start_course
WORKDIR /work
In the Dockerfile, the teacher can modify the container by installing software, setting environment variables, copying files into the container etc.
It is good practice to install and configure as much as possible of the required software directly in the Dockerfile. See also the page about Docker best practices for tips and advice on how to write the Dockerfile.
Important
The teacher should never add datasets or other potentially sensitive information to the Dockerfile. Instead this should be stored e.g., in a UCloud project and mounted to the UCloud job when the students run the course.
The course can be started with start_course.sh, also referred to as the starting script.
In a newly created course, the starting script is minimal and looks like this:
#!/bin/bash
function exit_err {
printf "%s\n" "$1" >&2
exit 1
}
while getopts ":s:" option; do
case "$option" in
s) INITIALIZATION="$OPTARG" ;;
:) exit_err "Missing argument for -$OPTARG" ;;
*) exit_err "Invalid option -$OPTARG" ;;
esac
done
if [[ -f "$INITIALIZATION" ]]; then
printf "\n======================\n"
printf "Running Initialization\n"
printf "======================\n\n"
case "$INITIALIZATION" in
*.txt)
pip install --user -r "$INITIALIZATION" || exit_err "Failed to install packages from $INITIALIZATION"
;;
*.yml|*.yaml)
conda env update --file "$INITIALIZATION" || exit_err "Failed to update environment using $INITIALIZATION"
;;
*.sh)
bash "$INITIALIZATION" || exit_err "Failed to execute script $INITIALIZATION"
;;
*)
exit_err "File format not correct. Initialization must be specified in a *.txt, *.yml/yaml, or *.sh file."
;;
esac
fiThe script first fetches the parameters using getopts and then proceeds to run the initialization script if this has been specified.
The teacher can specify and implement necessary mandatory and/or optional parameters in this script.
Two Python test scripts can be used by the teacher to test the course locally. Specifically, docker-build.py can be used to build the Docker image and docker-run.py can be used to run a Docker container.
Note
Be sure that Docker is running on the computer before running either of the two test scripts.
When a teacher wants to build the course's Docker image, they should first of all open a terminal (MacOS/Linux) or PowerShell (Windows).
Then, they must change the current working directory to the <course-start-date> folder in their course folder (see the course folder structure).
Next, the teacher must run docker-build.py to build the Docker image:
$ python docker-build.pyThe command is the same on Windows machines.
Running the command above will produce the following lines:
[INFO] Starting build of ../Courses/SDU/test__1234/2024-09-01/Dockerfile.
[INFO] BE PATIENT ... Building the image may take a while.
[INFO] Building complete. The image 'dreg.cloud.sdu.dk/ucloud-courses/sdu_test__1234:2024-09-01' and available under 'Images' in Docker Desktop.
[INFO] Use 'python3 docker-run.py' to start a container.Note
Building Docker images can take some time - especially for large images.
Once the build is complete, the Docker image will be available e.g. under Images in Docker Desktop.
Tip
The teacher can re-build the Docker image with docker-build.py several times.
Re-building the image overwrites the previous version of the image.
When the Docker image has been built with docker-build.py, it is possible to start a Docker container with docker-run.py.
If the teacher opens the file docker-run.py, they can specify the container run using the four variables INTERACTIVE_MODE, PORT, VOLUMES, and START_COMMAND. How to specify these variables is explained in section 2.
An example of the docker-run.py variable setting and corresponding starting script can be found here. In this case the demo covers the case of a UCloud course which uses the jupyterlab base image.
In this specific case, where PORT = 8888, the JupyterLab interface will be accessible from a browser on the teacher's own machine at localhost:8888.
Running a Docker container in interactive mode means that one gets access to a bash shell inside the running container.
Running a container in interactive mode can be useful from a testing point of view because it allows the teacher to check if files and folders are mounted correctly, have the right permissions etc. It can also be useful for debugging purposes.
A container can be started interactively by setting INTERACTIVE_MODE = "True" in docker-run.py.
If a container is started in interactive mode the START_COMMAND specified in docker-run.py will not be executed.
A container can also be started non-interactively by setting INTERACTIVE_MODE = "False" in docker-run.py. In this case, the START_COMMAND from docker-run.py will be executed inside the container immediately after the container is started.