Skip to content

eecs-autograder/autograder-full-stack

Repository files navigation

This repository contains Docker and other configuration files needed to run and deploy the autograder system.

Announcements

  • Aug 26, 2024: Release 2024.08.v0 is out. See https://github.com/orgs/eecs-autograder/projects/2/views/1 for a list of addressed issues.
    • Changes to the "Upgrading (Production Deployments)" section of this document regarding upgrade requirements.
    • autograder-server and ag-website-vue submodules now use calendar versioning.

Website UI Documentation

Documentation on how to configure projects, test cases, and more through the web interface can be found at https://eecs-autograder.github.io/autograder.io/

Versioning

Versioning Convention Updates

August 2025 - present

We continue to use calendar versioning, but we remove the v from the version number in previous versions:

{yyyy}.{mm}.{minor version}.{pre-release modifier}

We generally follow Python conventions E.g., our next major release at time of writing will be 2025.08.0.

ag-client-typescript now also uses calendar versioning.

Jan. 2021 - July 2025

As of Jan. 2021, we use the following version scheme for release tags in this repo (autograder-full-stack):

{yyyy}.{mm}.v{X}
  • {yyyy} is the year of the release (e.g. "2021").
  • {mm} is the month of the release (e.g. 01, 06, 08, 09 for Jan, June, Aug, or Sept).
  • {X} is the minor version number, incremented for smaller changes (patches, bug fixes) between major releases.

(Written on Aug. 23, 2024): Starting with our next release, we will start using this calendar versioning scheme for the autograder-server and ag-website-vue sub-repositories. Note that since npm doesn't allow the "v" in the minor version portion, we will omit it in the package.json file in that repository. We will also omit the "v" in autograder-server for symmetry. These version labels will be synchronized (i.e., the submodules will have the same version as this repo's release tags) to make it easier to verify that the deployed repos are in sync. ag-client-typescript will continue to use semantic versioning.

Installation/Setup & Upgrading

Dev Setup

See this tutorial.

Swarm Production Setup

See this tutorial.

Single-server Production Setup

See this tutorial.

Upgrading (Production Deployments)

We typically only release updates to the latest calendar version (e.g., 2025.08.x). In the case of a critical issue, we may decide to backport certain updates to prior versions.

Upgrading to 2025.08.0 or Later

To upgrade to the latest release, replace {version} below with "latest".

To upgrade to a specific release, run the following:

git fetch origin
git fetch --tags
git checkout --recurse-submodules {version}
git submodule update --remote --recursive

Check that each submodule is pointing at the commit labelled with that version:

git submodule foreach --recursive git log --max-count 1

If the above command only prints log messages for two submodules, run the following:

git submodule update --init --recursive
git submodule update --remote --recursive
git submodule foreach --recursive git log --max-count 1

Upgrading to 2024.08.v0 or Earlier

To upgrade from one version to the next, follow these steps:

  1. Pull the master branch in the autograder-full-stack repo and pull the latest tags.

    cd autograder-full-stack
    git checkout master
    git pull
    git pull --tags
    
  2. Checkout the tag for the version you want to upgrade to.

    # Replace {tag} with the appropriate version (e.g. 2021.01.v3)
    git checkout {tag}
    

    Legacy Note: If your deployment is behind by several major versions (the {yyyy}.{mm} portion of the version number), we recommend upgrading to each intermediate major version sequentially. This is important to ensure that database migrations run correctly.

    Updated Note: Starting with release 2024.08.v0, we will generally try to make it possible to upgrade from 2024.08.v0 straight to the newest version without upgrading to each intermediate version. If a release requires upgrading from a specific previous version, we will note this requirement in the announcements section of this document.

  3. Update the autograder-server and ag-website-vue submodules. If you've made changes to the submodules (such as changing config settings), you may need to stash them first and then re-apply. Git will warn you if you need to do so.

    git submodule update --remote
    
  4. Re-deploy the docker containers and apply database migrations. This step varies slightly depending on which deployment strategy you're using (e.g., single server, swarm). Please refer to the appropriate tutorial for the specific commands: swarm, single server.

Other Recipes and Things to Know

Upgrading Postgres

IMPORTANT: As of 2025.08.0, postgres 14 or later is required. The postgres version is no longer hard-coded in the docker compose files. Instead, we read it from the file autograder-full-stack/postgres_version and pass the value as a docker build arg. See the steps below for details.

Refer to the Postgres documentation for different possible upgrade approaches. Here we outline the steps needed to do a dump and restore upgrade. These steps assume we're upgrading to Postgres 14. Replace "14" with the version of Postgres you want. Replace ${postgres_container} with the name of the postgres container on your deployment. For single-server deployments, the postgres container name will be ag-postgres. Swarm deployments will need to find the container name with docker ps. We recommend setting variables with these values to avoid mistakes.

  1. Schedule maintenance downtime.
  2. At the beginning of your maintenance window, stop or pause the django and nginx containers:
    # Use "pause" for swarm deployments. "stop" will work for single-server
    docker pause ${django_container} ${nginx_container}
    
  3. Make sure there are no submissions being graded. You may also choose to stop/pause your grading worker containers.
  4. Perform a full system backup.
  5. Dump the current database contents:
    docker exec -it ${postgres_container} pg_dump --username=postgres --format=c postgres -f /db_backup
    docker cp ${postgres_container}:/db_backup .
    
    Store the db_backup file somewhere safe.
  6. In your docker compose file, add a new postgres volume for the new version. The example below uses Postgres 14 as an example version.
    ...
    volumes:
    ...
    # old version, keep it as-is
    pgdata: {}
    # ADD THIS LINE. Replace "14" with the version of postgres you want to upgrade to
    pgdata14: {}
    ...
  7. (2025.08.0 and later). Update the version of postgres in autograder-full-stack/postgres_version.
    echo 14 > postgres_version
    
    • (2024.08.0 and earlier). In your docker compose file, edit the postgres service to point at the new volume and to use the desired version.
      # Replace "14" with the version you want to upgrade to.
      postgres:
      # Don't change other settings
      ...
      # CHANGE THIS to the version you want
      image: postgres:14
      volumes:
          # VERY IMPORTANT: Change "pgdata" on the left side of the colon to the
          # name of the volume you created in the previous step.
          - pgdata14:/var/lib/postgresql/data/
      ...  # Settings copied from the above service block
  8. Rebulid and re-up the updated postgres service. DO NOT apply django migrations. On a single-server deployment, the following commands will do so:
    AG_POSTGRES_VERSION=$(cat postgres_version) docker compose -f docker-compose-single.yml build postgres
    AG_POSTGRES_VERSION=$(cat postgres_version) docker compose -f docker-compose-single.yml up -d postgres
    
    On swarm deployment, rebuild postgres with the following command, then redeploy the stack:
    AG_POSTGRES_VERSION=$(cat postgres_version) docker compose build
    docker compose push
    docker stack deploy -c docker-compose.yml ag-stack
    
  9. Restore the dumped contents into the updated postgres service. Note for swarm deployments: the name of the postgres container will have changed.
docker cp db_backup ${postgres_container}:/
docker exec -i ${postgres_container} pg_restore --username=postgres --format=c -d postgres /db_backup

(2024.08.0 and earlier only).

Below are snapshots of what the changes to docker-compose-single.yml might look like during this process.

Start (your file may have some differences):

postgres:
  container_name: ag-postgres
  restart: unless-stopped
  image: postgres:9.5
  volumes:
    - pgdata:/var/lib/postgresql/data/
  environment:
    POSTGRES_PASSWORD: 'redacted'

...

volumes:
  redisdata: {}
  pgdata: {}
  rabbitmqdata: {}
  sandbox_image_registry_data: {}

New volume:

postgres:
  container_name: ag-postgres
  restart: unless-stopped
  image: postgres:9.5
  volumes:
    - pgdata:/var/lib/postgresql/data/
  environment:
    POSTGRES_PASSWORD: 'redacted'

...

volumes:
  redisdata: {}
  pgdata: {}
  pgdata14: {}  # NEW
  rabbitmqdata: {}
  sandbox_image_registry_data: {}

Update service:

postgres:  # CHANGE
  container_name: ag-postgres  # DO NOT CHANGE
  restart: unless-stopped
  image: postgres:14  # CHANGE
  volumes:
    - pgdata14:/var/lib/postgresql/data/
  environment:
    POSTGRES_PASSWORD: 'redacted'

...

volumes:
  redisdata: {}
  pgdata: {}
  pgdata14: {}  # NEW
  rabbitmqdata: {}
  sandbox_image_registry_data: {}

Useful scripts

If you want to automate a task using a scripting language, you can use the Python HTTP client found at https://github.com/eecs-autograder/autograder-contrib and some ready-to-use python scripts at https://gitlab.eecs.umich.edu/akamil/autograder-tools.

  • IMPORTANT: Make sure to use the correct URL for your deployment. In the former set of scripts, this is configurable with command-line arguments. In the latter, you may need to modify the source code.

Giving a user permission to create courses

Run the following in a django shell (docker exec -it ag-django python3 manage.py shell):

from django.contrib.auth.models import User, Permission
# UPDATE the email address
user = User.objects.get(username='@umich.edu')
user.user_permissions.add(Permission.objects.get(codename='create_course'))

Submissions not being processed for one project

This issue should be fixed as of 2024.08.0. Notes on how to resolve are below just in case.

Occasionally a new project won't be correctly registered with the grading workers, and so submissions won't get past "queued" status. To manually register the project, run the following in a django shell:

from autograder.grading_tasks.tasks import register_project_queues
# UPDATE the project_pks list. The project primary key can be found in the url when viewing the project on the website.
register_project_queues(project_pks=[339])

Submission(s) stuck at "being graded" status

This is now possible to resolve through the UI. See https://eecs-autograder.github.io/autograder.io/how_tos.html#rerunning-a-stuck-or-errored-submission

Creating a Custom API Token

To create a custom api token, run the following in a django shell:

from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token

# Replace <username> with whatever you want.
user = User.objects.create(username='<username>@autograder.io')
token, created = Token.objects.get_or_create(user=user)
# If that username is taken, try another one.
assert created

# Securely share this token with whomever needs it.
print(token)

Add the username (<username>@autograder.io) to the appropriate roster for your course to give the token user the permissions it needs.

Development & Release Branches: Protocols and Workflow

This section is intended for developers.

Legacy "master" branch

As of 2025.08.0: Each release now has its own branch, and the master branch will no longer point to the latest version. Instead, the latest release will have the tag latest. Either checkout the latest tag or the release branch for the release you want to use.

Giving each release its own branch will make it easier for us to apply patches to multiple release versions when needed.

"develop" branch

Use feature branches for all changes, and make a pull request against the develop branch.

This repo has two submodules: autograder-server and ag-website-vue. The develop branch is for changes based on the develop branch of the submodules. Update the submodules' develop branches when preparing a release or when starting work on a feature that depends on new autograder-server or ag-website-vue commits. Use the following steps on your feature branch:

# Fetch latest submodule commits
git submodule update --remote
# git status should show new commits in the submodule
git status
git add autograder-server ag-client-typescript
git commit -m "Update submodules"

"release-*" branches

Name release branches as release-YYYY.MM.x, replacing YYYY with the full year and MM with the zero padded month (e.g., release-2024.08.x).

IMPORTANT: When you create a release branch, update the branch field in the autograder-server and ag-client-typescript entries of .gitmodules to point to the corresponding release branch in the submodules. Then run git submodule update --remote and commit the changes.

Do NOT merge or rebase directly between the develop and release branches. Once a release branch is created, it should only be updated with bugfix- or (rarely) feature-style branches. Squash-and-merge for this type of PR. After the squashed branch is merged into a release branch, cherry-pick the squashed commit on top of develop and open a pull request to merge the changes into develop.

The version of README.md (this file) on the develop branch is the source of truth. Update this file on release branches just before publishing a release. If instructions differ across releases, include both, and label which version the instructions apply to.

Publishing a release

Publishing a new release is a multi-step process. Run ./dev_scripts/start_release.sh {version} and follow the instructions printed.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •