CanvasManager · guide for new users · updated October 2026

Getting Started with CanvasManager

Run a Canvas course from a folder of markdown files: set it up in ten minutes, see the semester on a calendar, and publish with one click.

What CanvasManager is

CanvasManager is a web app you run on your own machine that turns a folder of markdown files into a Canvas course. Every assignment, quiz, page and lecture is a plain text file. You edit the files (in the app or in any editor), the app shows them on a semester calendar, and one click publishes an item to Canvas with its dates, rubric, module placement and formatting.

Files are the truthCourse content is markdown in a folder you own. Put it in git and you get history, branches and diffs for free.
Calendar firstSee the whole semester at once. Drag an item to a new day and its dates move.
One-click publishCreate or update the Canvas item, its rubric and module entry. The calendar shows what is out of sync.
Reuse next semesterImport a previous semester's course and shift everything onto the new dates.
Course calendar for Fall 2026 showing August and September with assignments (pencil icon) and pages (document icon) on their due days, a Committed git button in the header, and a module list on the right
The course view: calendar on the left, modules on the right. The icon on each pill shows its type.

How your course lives on disk

You point the app at one storage folder. Inside it, each course is a folder with a settings.yml and one folder per module. Most people keep one folder per class and a subfolder per semester.

faculty/                                  ← the storage folder (mount this)
  globalSettings.yml                      ← which course folders to show in the UI
  4620_Distributed/
    2026-fall/
      Modules/
        settings.yml                      ← dates, class days, defaults, grading categories
        00 - lectures/
          week-01/
            1-Monday.md
            3-Wednesday.md
        01 Chaos KV/
          assignments/
            W01 Single-Node KV Store.md
          quizzes/
            W03 Reading Quiz.md
          pages/
            KV Wire Protocol Spec.md
        02 Async Messaging/
          ...

globalSettings.yml lists the course folders you want to see right now, so old semesters can stay on disk without cluttering the app:

courses:
  - path: ./4620_Distributed/2026-fall/Modules/
    name: Distributed
  - path: ./3630_Mobile/2026-fall/Modules/
    name: Mobile

The app edits this file for you when you add or import a course. You can also edit it by hand.

Setting it up

You need Docker and a Canvas API token. Everything runs in one container.

Canvas token

  1. In Canvas, open Account › Settings and scroll to Approved Integrations.
  2. Click New Access Token, give it a purpose like “CanvasManager”, and copy the token. Canvas shows it only once.
  3. Create a file named .env next to your compose file:
CANVAS_TOKEN=paste-your-token-here
# optional, only for the Classroom 50 (GitHub Classroom) buttons,
# and for pulling and pushing a course repo on GitHub:
GH_TOKEN=ghp_...
# optional, only for the "Explain with AI" button on the error list;
# any OpenAI-compatible endpoint (OpenAI, OpenRouter, a local Ollama...):
AI_BASE_URL=https://api.openai.com/v1
AI_API_KEY=sk-...
AI_MODEL=gpt-4o-mini

The repository’s .env.example has these lines with more endpoint examples.

The token acts as you in Canvas. Keep .env out of git.

Docker Compose

Save this as docker-compose.yml and adjust the three volume paths to your machine:

services:
  canvas_manager:
    image: snowcollege/canvas_management:4
    user: "1000:1000"
    container_name: canvas-manager
    ports:
      - 3000:3000
    env_file:
      - .env
    environment:
      - storageDirectory=/app/storage
      - TZ=America/Denver
      - NEXT_PUBLIC_ENABLE_FILE_SYNC=true
    volumes:
      - ./globalSettings.yml:/app/globalSettings.yml
      - ~/projects/faculty:/app/storage
      - ~/projects/facultyFiles:/app/public/images/facultyFiles
LineWhy
user: "1000:1000"Files the app writes are owned by you, not root. Use your own uid if it differs (id -u).
TZDue times are interpreted in this zone. Set it to your campus.
globalSettings.ymlCreate it first with just courses: [].
/app/storageYour course folder. Make it a git repo; the course page can then commit, pull and push it (see Git).
facultyFilesOptional. Images you reference from markdown; see Images and files.

First run

echo "courses: []" > globalSettings.yml
docker compose pull
docker compose up -d

Open http://localhost:3000. An empty course list with two buttons is what success looks like.

When a newer image is on Docker Hub the home page shows a banner with the commits it contains. Nothing updates on its own; run docker compose pull && docker compose up -d when you want it.

Adding a course

Home page listing courses grouped by semester with Add New Course and Import Existing Course buttons
The home page groups courses by semester.

Course settings

Open a course and click Course Settings in the top right. Set these before you start publishing.

Course settings showing the seven day buttons with Monday, Wednesday and Friday as class days, a line explaining the three states, semester start and end, and the Classroom 50 section
Class days drive the calendar shading and the date picker; semester dates bound the calendar. Click a day to cycle it between class day, no class and hidden.
SettingWhat it does
Days of weekClick a day to cycle it through three states: class day (shaded on the calendar and offered by the date picker), no class, and hidden, a day without class that the calendar narrows to a strip so the class days get the room. See the calendar.
Semester start and endBounds the calendar and the “next class day” helper.
Classroom 50Optional GitHub Classroom integration. Skip it unless you use Classroom 50.
Default submission types and upload typesWhat new assignments start with.
Default due time and lock offsetThe time of day dragged items get, and how many hours after due an assignment locks.
Assignment groupsCanvas grading categories and their weights. Update Assignment Groups In Canvas pushes them; do that once at the start of a semester.
Students and GroupsRead-only views of the Canvas roster and group sets, used by the editor. See the Group Assignments & Student Schedules guide.
HolidaysDays with no class. They are labeled on the calendar and struck through in the date picker.
Settings showing default due time, lock offset and the assignment groups with weights
Assignment groups are Canvas grading categories. Each assignment names one with AssignmentGroupName.
Holiday settings as a small YAML block with the parsed dates listed underneath
Holidays are a small YAML block; the app lists the dates it understood underneath.

The calendar

The course page is a calendar of the whole semester with the module list beside it. Each item is a pill on its due day, and the border tells you its Canvas state:

Calendar with the 01 Chaos KV module expanded on the right, listing its items grouped by week and weekday
Expand a module to see its items by week. Sort by Due Date reorders them in Canvas; New Item creates a file.

The icon at the right of each pill tells the type apart: a blue pencil for an assignment, an amber question mark for a quiz, a violet page for a page. The same icon sits before the item’s name at the top of its editor.

Things you can do from the calendar:

Hiding days. Days your class never uses, often Saturday and Sunday, can be hidden in course settings: click a day until it is struck through. The calendar then draws that day as a narrow strip with just the date, so the days you teach get the width. Anything due on a hidden day still shows, as a small type icon in the strip that opens the item, and you can still drag items onto the strip.

Day buttons in course settings with Sunday and Saturday struck through with dashed borders, Monday, Wednesday and Friday filled as class days, and Tuesday and Thursday outlined as no class
Sunday and Saturday set to hidden in course settings.
Calendar for August and October with Sunday and Saturday drawn as narrow strips showing only the date, and a pencil icon in the Saturday August 29 strip for an assignment due that day
Hidden days are narrow strips. The pencil in the strip for Saturday the 29th is an assignment due that day; click it to open the assignment.
Right-click menu on an assignment offering View in Canvas, Compare with Canvas, Update in Canvas, a green Published entry, then Delete from Canvas
The right-click menu. This assignment is already published, so after Update in Canvas there is a disabled green Published instead of Publish in Canvas.

Editing content

Every editor has the same shape: the file on the left, a live preview on the right, and a footer that says how the file stands against Canvas. Changes save to disk as you type, and the preview shows parse errors at the top in red. The file is also watched, so editing it in another program updates the app immediately.

A file that can’t be read (say a quiz answer written a. instead of a), edited outside the app) is not dropped silently. Its module shows a red ⚠ count, and the file is listed at the top of the module in red under Can’t be read, click to fix. If the file’s date line still reads, it is also on the calendar on that day, as a red dashed pill with a warning icon; hover it to read the parse error. Clicking either one opens the file as plain text with the syntax help beside it and the parse error on the right. Every change is saved as you type, and the regular editor opens by itself as soon as the file parses. File history at the bottom goes back to a version that worked, if the file is in git.

Course calendar with the 01 Chaos KV module expanded; its header shows a red warning badge with 1, and above its items a red Can't be read, click to fix label lists W03 Reading Quiz with a wavy red underline. A red 1 error pill sits at the bottom center of the screen
A quiz that doesn’t parse is listed in red at the top of its module, and the error pill at the bottom counts it.
Calendar for September with a red dashed W03 Reading Quiz pill and a warning icon on Monday the 14th, and its hover card reading Quiz W03 Reading Quiz can’t be read, the parse error question 3: no answers when detecting question type, and Click to open the file and fix it
The same quiz on the calendar on its due date. Hover shows the parse error; click opens the file to fix it.
The quiz opened as plain text, with the quiz syntax help on the left, the file in the middle, and on the right the heading This file doesn't parse, an explanation, the error question 3: no answers when detecting question type, and an Explain with AI button
The file opened for fixing. The error names the question, and the help on the left shows how answers are written.

Assignments

An assignment file is a settings block, a --- line, the description in markdown, and a ## Rubric heading followed by the criteria.

Assignment editor with the frontmatter, markdown description and rubric on the left, the rendered preview on the right, and a footer reading In sync, Published with a View in Canvas button
Settings above the ---, markdown below, rubric at the end.
UnlockAt: 
LockAt: 09/04/2026 23:59:00
DueAt: 09/04/2026 23:59:00
AssignmentGroupName: Assignments
Classroom50Slug: 
SubmissionTypes:
- online_text_entry
- online_upload
AllowedFileUploadExtensions:
- pdf
---

Next week you'll implement primary-backup replication...

## Rubric

- 10pts: Formatting
  - 10pts: proper margins, font size, spacing, and headings
  - 7pts: margins and font size correct but missing heading styles
- 5pts: Student response to reading
- 2pts: (extra credit) Went beyond the prompt
Assignment editor with the help panel open on the left, filtered by the search rubric so only the matching topics show, with the matches highlighted
The ? button opens the reference beside the editor. Every topic starts collapsed; type in the search box to show only the topics that match, or use Expand all.

Quizzes

A quiz file has its own settings block, then one question per section separated by --- lines. The preview renders each question the way Canvas will.

Quiz editor showing quiz settings, a multiple-choice question with feedback and a short-answer question, with the rendered preview on the right and In sync, Published in the footer
Questions are separated by --- lines. A * marks the correct choice; + and - lines are feedback for right and wrong answers.
TypeHow to write it
Multiple choicea) ..., b) ...; a * in front marks the correct one
Multiple answers[*] right and [ ] wrong checkboxes
Essaya last line of essay
Short answera last line of short_answer (graded by hand), or starred answers followed by short_answer= to auto-grade
Numerical= 2.5 for an exact answer, = [2.4, 2.6] for a range
Matching^ left - right lines; ^ - extra adds a distractor
Multiple dropdownsmatching lines split into groups by blank lines; each prompt gets its own dropdown of its group's answers
Fill in multiple blanks[ans1] placeholders in the question, then [ans1] = answer for each blank; more accepted answers for the same blank go on the next lines as = answer
Quiz editor with the help panel searched for dropdown, showing the Matching and Multiple dropdowns topics with the word highlighted
Searching the quiz help for “dropdown”.

Pages

Pages are plain markdown with one setting, DueDateForOrdering, which only decides where the page sits on the calendar and in the module.

Link to a page the way Canvas will resolve it, by its title in lowercase with dashes: [Belt Tour](../pages/belt-tour), from any page, assignment or quiz. The preview follows such a link to the page in the app, keeping anything after a #.

Page editor with a markdown spec on the left and its rendered form on the right
Pages are markdown with a single ordering date.

Lectures

Each class day has one lecture file with a name, a date and markdown notes. Click a day's title on the calendar to open it. preview opens a full-width view for projecting.

Lecture editor showing an outline and notes for a Wednesday class with the rendered preview on the right
Lecture notes render in the preview; the preview button opens them full screen.

Editor helpers

The settings block has autocomplete. A blank line offers the keys the file is missing; a key like AssignmentGroupName offers its valid values; a - under a list offers the list's options. Date fields open a date and time picker that knows your class days and holidays.

The help panel is searchable: type a word like rubric, numerical or schedule to filter it to the topics that mention it. Expand all and Collapse all sit beside the search box, and every example has a Copy button.

Date and time picker open beside a DueAt line
Put the cursor on a date line and pick from the calendar.
Blank frontmatter line offering the keys the file does not have yet
On a blank line, the keys you have not used yet.

Publishing to Canvas

Each editor’s footer says where the item stands and shows the one button you need next:

Everything else is behind the arrow on the right edge of that button: View in Canvas, Compare with Canvas, Update in Canvas anyway, File history, Classroom 50, and, at the bottom in red, Delete from Canvas (removes it there and leaves your file alone) or Delete locally for an item that is only on disk. At the left are the help button, previous and next item, and Back to calendar. On a phone all of these are in the ☰ menu.

Editor footer reading 1 difference from Canvas in amber with an Update in Canvas button, and the menu of its split button open above it listing View in Canvas, Compare with Canvas, File history, Classroom 50 and, in red below a divider, Delete from Canvas
An assignment that differs from Canvas. The amber text opens the compare page; the arrow on the right of the button holds the rest, including the file’s history.

Published quiz? Click “Save it now”. After updating the questions of a published quiz, students keep getting the old questions until you open the quiz in Canvas and click Save it now. The Canvas API cannot do that step. The app reminds you with a message that links to the quiz.

The calendar border and the right-click menu do the same jobs from the course page, so a typical week is: write the files, glance at the calendar for grey and red pills, publish or update from the menu.

Publishing uses your Canvas token, so it can do anything you can. The app never deletes a Canvas item unless you ask it to.

Compare with Canvas

When an item’s border is red, Compare with Canvas (the amber differences from Canvas text in the editor footer, the menu on the footer’s main button, the right-click menu, and the red pill’s hover card) opens a page that lists every difference between your file and Canvas:

Compare with Canvas page for a reading quiz showing the settings and all seven question rows matching, the description side by side, and the Update Canvas footer
The compare page. Matching rows have a green dot, differing rows a red one, and the badge at the top counts the differences.
Question rows on the compare page where question 3 reads type essay for the file and type short answer for Canvas, with a red dot, between matching questions
A question that differs shows only what differs: the file now has question 3 as an essay, but Canvas still has it as short answer.

Images and files

Mount a folder of images at /app/public/images/facultyFiles (see the compose file) and reference them from markdown in an assignment, quiz or page:

![formulas](/images/facultyFiles/1405/lab-04-simple-math-formulas.png)

Keep images in a separate repo from your course text so the text repo stays small.

Git: commit, sync, history

When your course folder is in a git repository, the course page’s header has a git button beside Reload Canvas Data. It reads Committed, or 3 uncommitted with an amber dot when files in this course have changed, with ↑2 for commits waiting to be pushed and ↓1 for commits waiting to be pulled.

Course files in git dialog listing two uncommitted changes, an edited assignment and an added page, a commit message box filled in with a summary of both, a Commit button, a line reading Up to date with the remote with a Pull and push button, a checkbox to commit automatically after adding or updating something in Canvas, and the last commit to the course
The git button opens this. The commit message is written for you from what changed; edit it if you like.

To pull and push a GitHub repository from the container, set GH_TOKEN in .env to a token that can write to the repo; a remote written as git@github.com:... is reached over https with that token. With your own ssh keys mounted in the container, those are used instead.

File history. Every assignment, quiz and page has a File history item in the menu on its editor’s footer. It lists the commits that changed the file, renames included. Pick one to see what changed between that version and the file now, and Restore this version to write it back over the file. Restoring doesn’t commit anything; if the file has changes that were never committed, it warns you first, because those are not in git to get back.

File history page for an assignment listing two commits on the left, the older one selected, and on the right a diff where a removed line in red is replaced by two green lines adding a leaderboard screenshot to the submission, with Back, Edit file and Restore this version buttons at the bottom
File history with the original version selected: one line of the submission instructions has changed since.

When something goes wrong

Every error the app runs into while it is running, a file that doesn’t parse, a failed Canvas request, a pull that couldn’t merge, is kept in a list. While any of them are unfixed, a red pill at the bottom center of the screen counts them; click it to see the list.

Errors this session page with one entry: Reading quiz W03 Reading Quiz in module 01 Chaos KV, the time, the parse error message, and Explain with AI, Open quiz and Dismiss buttons. A note above says to set AI_BASE_URL and AI_MODEL to enable explanations
The error list. An error that happens again is counted, not listed twice, and one that has since worked, like a file that parses again, is marked fixed.

Tips

Recent changes

WhenWhat changed
Oct 2026Opening a course whose term has ended no longer shows a roster.groupSets … 403 error: Canvas won’t list group sets for a finished course, so it shows none.
Oct 2026Compare with Canvas checks a quiz’s password, allowed attempts, shuffle answers, show correct answers and one question at a time, so changing only one of them no longer shows the quiz as in sync.
Oct 2026Compare with Canvas compares short-answer answers as plain text, so an answer like + or a*b*c no longer shows as different when it matches.
Oct 2026Update in Canvas refuses to change a quiz’s point total once students have started, since their scores are out of the total they were given.
Oct 2026Compare with Canvas shows what students got on each quiz version they took, next to the file.
Oct 2026Compare with Canvas shows every quiz question in full, answers included, marking the parts that differ, and says when it last read Canvas.
Oct 2026Update in Canvas leaves a quiz’s questions alone when they already match the file, so a settings-only change to a published quiz no longer needs Save it now.
Oct 2026Pages are compared with Canvas on their content: an edited page gets a red border, a difference count in its footer, and a Compare with Canvas page.
Oct 2026Page links written for Canvas, like ../pages/belt-tour, open the page in the preview instead of a missing file.
Oct 2026Classroom 50 links send students to the assignment’s accept page, and setup recognizes the gh-teacher extension when the Docker image copies it in.
Oct 2026On the calendar, hovering a day’s title fades in Add lecture notes when the day has none, and the + button has an Add assignment / quiz / page tooltip.
Oct 2026Compare with Canvas lines quiz questions up by content, so deleting, adding or moving one question shows as one difference instead of marking every question after it as changed.
Oct 2026Requests to Canvas are queued and retried when Canvas rate-limits them, so adding several items in a row or a long quiz no longer loses requests (or quiz questions) to 429 Too Many Requests.
Oct 2026Not being published is no longer counted as a difference: the compare page drops its Published row and says in sync, while the calendar border stays red until you publish.
Oct 2026Git from the course page: commit a course’s changes with a message written for you, pull and push (merging when there is no conflict), optionally commit after each publish, and see or restore any earlier version of a file.
Oct 2026Error list: a pill counts this session’s errors and opens a list of them, each with an Explain with AI button that uses any OpenAI-compatible endpoint you configure.
Oct 2026A file that doesn’t parse is listed in red in its module, shown on the calendar on its date when that line still reads, and opens as plain text to fix, instead of disappearing.
Oct 2026Hidden days: a day without class can be hidden in course settings, and the calendar narrows it to a strip.
Oct 2026Images are uploaded when you publish an assignment, quiz or page, not while you type; a changed image is uploaded again, a missing one stops the publish, and web images and Mermaid diagrams are no longer copied into Canvas files.
Oct 2026Expanded modules and the module list’s scroll position are remembered per course.
Oct 2026Publish in Canvas button in the editors and the right-click menu, showing Published once students can see the item.
Oct 2026Fill in multiple blanks quiz questions, with several accepted answers per blank.
Oct 2026Distinct calendar icons for assignments, quizzes and pages.
Oct 2026Calendar titles wrap under the type icon instead of beside it, and the editors show the same icon before the item’s name at the top.
Oct 2026Compare with Canvas and the quiz editor’s footer compare every quiz question too: type, points, text, answers and feedback. The calendar does the same for the next four weeks of quizzes.
Oct 2026The editor footer is one row: it says whether the file is in sync with Canvas and shows the one button you need next, with the other actions behind the arrow on that button.
Oct 2026Renaming an assignment, quiz or page no longer spins forever on a name with a character a file name cannot hold (like / or :); the rename box says which character to remove.
Oct 2026The editor help is searchable and split into collapsible topics with copyable examples. It now covers every quiz setting and question type, numerical questions, rubric deductions, and links between course files.
Oct 2026Multiple dropdowns quiz questions.
Oct 2026Update in Canvas replaces a quiz’s questions too, warns first if students have started, and reminds you to click Save it now on a published quiz.
Oct 2026Repeated error messages show once, and errors stay on screen until closed.
Sep 2026Compare with Canvas page; the calendar lists every difference instead of the first one, and quiz settings can be updated in place.
Sep 2026Group assignments, per-student schedules, the date picker and settings autocomplete. See Group Assignments & Student Schedules.