Skip to content

Installing and running for local course development

This page describes the procedure to install and run your course locally within Docker. You can develop course content locally following the instructions below, or using the in-browser tools.

Installation instructions

Regardless of which operating system you are using, you will need to install the appropriate version of Docker Desktop.

If you are using Windows, you are strongly encouraged to also use WSL 2 to run PrairieLearn. WSL 2 provides a Linux environment that runs alongside Windows, and makes better use of modern CPU virtualization features.

Here are the instructions to install WSL 2 and enable its integration with Docker:

Warning

We do not currently support a Windows environment without WSL 2, due to extreme performance issues, limitations related to file permissions in job folders, as well as issues associated to file formats. While there are ways to run PrairieLearn in this environment, it may not provide the same experience that a student would see in a production environment, and as such it is discouraged and not documented. In all cases below, the Windows examples assume that WSL 2 is installed.

Cloning your course repository

If you are running PrairieLearn with the example course only, you may skip this section.

When you request your course, you will typically receive a GitHub repository URL to your course's content. You may use Git to clone (make a local copy of) this course content in your own computer. Make note of the directory you are cloning your course to. If you are working with multiple courses, you will need to store each course in a separate directory.

If you are using Windows, you have two options to store your course repository(ies):

  • Store your course content inside the WSL 2 instance. This option typically provides the best performance when running PrairieLearn locally. You can clone the repository using git commands inside your WSL shell. Note that, in this case, you will need to either update your files using WSL tools and editors, or access the files using the Linux file systems. Instructions to do so are listed here. In this case, keep track of the path used by your course inside WSL (e.g., $HOME/pl-tam212)
  • Store your course content in the Windows file system itself (e.g., in your Documents or Desktop folder, or elsewhere inside the C: drive). If you are using this option, you will need to translate the Windows path into the WSL mounted path in /mnt. For example, if your course is stored in C:\Users\mwest\Documents\pl-tam212, then the directory you will use is /mnt/c/Users/mwest/Documents/pl-tam212 (note the change of prefix and the replacement of backslashes with forward slashes).

Running instructions

To run PrairieLearn using the example course only, open a terminal window and type the command:

docker run -it --rm -p 3000:3000 prairielearn/prairielearn

To use your own course, use the -v flag to bind the Docker /course directory with your own course directory. For example, if your course is stored in $HOME/pl-tam212, the command is:

docker run -it --rm -p 3000:3000 -v $HOME/pl-tam212:/course prairielearn/prairielearn

Make sure to replace the course path with your own course directory. To use multiple courses, add additional -v flags (e.g., -v /path/to/course1:/course -v /path/to/course2:/course2). You may use up to nine courses through this method, using the mount points: /course, /course2, /course3, ..., /course9.

If you are running on Windows, run the command above in a WSL 2 shell, not on PowerShell or the Command Prompt.

After running the command above, you should see a message that says:

PrairieLearn server ready, press Control-C to quit

Once that message shows up, open a web browser and connect to http://localhost:3000/pl.

When you are finished with PrairieLearn, type Control-C on the terminal where you ran the server to stop it.

Support for external graders and workspaces

There are a few extra steps needed to run PrairieLearn locally with support for external graders and workspaces.

First, create an empty directory to use to share job data between containers. This directory can live anywhere, but needs to be created first and referenced in the Docker launch command. This directory only needs to be created once. If you are running Windows, the directory should be created inside the WSL 2 instance. You can create this directory using a command like:

mkdir "$HOME/pl_ag_jobs"

Now, we can run PrairieLearn with additional options to allow the external grading or workspaces features. For example, if your course directory is in $HOME/pl-tam212 and the jobs directory created above is in $HOME/pl_ag_jobs, the new command is as follows:

docker run -it --rm -p 3000:3000 \
  -v "$HOME/pl-tam212:/course" `# Replace the path with your course directory` \
  -v "$HOME/pl_ag_jobs:/jobs" `# Map the jobs directory into /jobs` \
  -e HOST_JOBS_DIR="$HOME/pl_ag_jobs" \
  -v /var/run/docker.sock:/var/run/docker.sock `# Mount Docker into container so it can spawn others` \
  --add-host=host.docker.internal:172.17.0.1 `# Ensure network connectivity` \
  prairielearn/prairielearn
Why is this necessary?

In production, PrairieLearn runs external grading jobs and workspaces on a distributed system that can efficiently run many jobs in parallel. When developing questions locally, you won't have access to this infrastructure, but PrairieLearn allows you to still run external grading jobs and workspaces locally. To do this, it needs extra Docker command line arguments to provide two key capabilities:

  • PrairieLearn needs a way of starting up Docker containers on the host machine from within another Docker container. This is achieved by mounting the Docker socket from the host into the Docker container running PrairieLearn; this allows it to run "sibling" containers.
  • PrairieLearn needs to get job files from inside the Docker container running PrairieLearn to the host machine so that Docker can mount them to either /grade in the grading container or the home directory in the workspace container. This is achieved by mounting a directory on the host machine to /jobs in the PrairieLearn container, and setting an environment variable HOST_JOBS_DIR containing the absolute path of that directory on the host machine.

Development

If you want to contribute improvements or features to PrairieLearn, you will need to start up PrairieLearn differently. See the local installation documentation for more details.

Troubleshooting the --add-host option and network timeouts

If you are an advanced Docker user, or if your organization's network policies require it, then you might have previously adjusted the address pool used by Docker. If this conflicts with the Docker defaults, you might get a network timeout error when attempting to launch a workspace locally. In that case, you might need to adjust the IP address for the --add-host= option. You can find more technical details here: PL issue #9805, moby/moby PR 29376, docker/docs issue 8663.

If you are using macOS, then you may be able to remove the --add-host option entirely without any problems.

Upgrading your PrairieLearn Docker image

To obtain the latest version of PrairieLearn at any time, make sure PrairieLearn is not running (Ctrl-C it if needed) and then run:

docker pull prairielearn/prairielearn

After this, run PrairieLearn using the same commands as above.

Running a specific version of PrairieLearn

The commands above will always run the very latest version of PrairieLearn, which might be an unreleased development version. If you would like to run the version that is currently deployed, use the appropriate tag for the server you're using:

docker run -it --rm -p 3000:3000 --pull=always [other args] prairielearn/prairielearn:us-prod-live

Tip

The command above uses the --pull=always option, which will update the local version of the image every time the Docker command is restarted. If you keep a long-running container locally, make sure to restart the container when updates in the production servers are announced in the PrairieLearn GitHub Discussions page.

Additional tags are available for older versions. The list of available versions is viewable on the Docker Hub build page.