As part of the holiday season - I thought it would be interesting to pilot a learning management system for close friends and family to post content about something they are passionate about (e.g. photography, books, tech, knitting, etc.). There are several options out there which are open source and able to be self hosted.
I was curious about a couple - the main criteria being easily self hosted with docker. This lets me tweak the docker-compose spec to work with pangolin and lets me manage the reverse proxy usign traefik (supplied by pangolin). This has been my workflow for other self hosted apps and it works quiet nicely.
The system itself shouldn’t be too complicated, I am not planning on scaling the LMS to 30k users - it will be a group of < 10 people. In that regard I really only need rudimentary roles and concepts - basically it should be a couse composed of a series of blogs, videos, or voice-vers with limited content. Not planning on doing assessements and grading.
You may say that a private Youtube would be the best solution for hosting the videos, and while technically that would suffice the video portion of it, I think the value-add is really spending the time typing out the textual representation similar to a blog. We may end up using Youtube to host the videos rather than paying for the storage in an AWS S3 bucket or similar. Looking at some of the solutions out there, it’s also possible to embed presentations into the course which will be great for a “live classroom” setting.
The other functionality that is interesting is the mass email notifications (e.g. no-reply@learn.kenyon.app). There are some interesting services out there to achieve this type of functionality, one of the ones I found which seems easy, free and straightforward is resend.com. I linked it to my github and we are off to the races - the free tier has 3,000 email limit (send/receive) which is plenty for my use case.
LMS Platforms
Looking at the candidates there are a number of suitable alternaives I wanted to evaluate.
Clasroom.io
Classroom.io is a open source education platform that can be used for self hosting training material.
There is some existing documentation for a self hosted setup here in the docs: https://classroomio.com/docs/quickstart/self-hosting
Notes:
- Interesting platform and the first I can across searching for an open-source alternative to google classroom
- Developed out of nigeria (very cool)
- Not very easy to self host
- The setup used
supabasewhich was the first time I have heard of the tool, it is an open source version of firebase which I have used in the past for some app development. - Led me to learn about SMTP and
resend.comwhich was good to know a provider for the other LMS - Docs in general are pretty good but under-construction
- Maintained by a few developers on their free time
Conclusion: Due to the inability to self host this was shelved after a couple hours of investigation.
Learnhouse
Learnhouse is a more self-hosted friendly project.
Notes
- It provides a simple intuitive UI, aligned with my use case
docker composefriendly, somewhat easy to understand the environment variables and setup- Disliked the frontend and the backend were hosted in the same container with an nginx reverse proxy
- No dark mode :/
Conclusion: Overall easy to customize, but the nginx reverse proxy and lack of separation for frontend/backend poses issues hosting with pangolin - haulted after about an hour of investigation.
OpenEdx
The flagship app for open source education - it is a beast.
Notes
- Comprehensive LMS - overkill for my use case, intended to be used at scale. Many user roles, etc.
- Recommended tool
tutorfor self hosting, takes away the complexity of setup (able to host local instance out of the box) - Uses Caddy as the reverse proxy
- Ability to import courses using an open XML spec (OLX)
Conclusion: Very comprehensive, likely too complex for what is required. May be made to work if no other suitable solution. Tutor is a nice abstraction, but may make self hosting with pangolin more difficult.
Canvas
Canvas LMS is a widely used LMS in the United States - the institution I attended for university used Canvas.
Notes
- Open source
- Complicated setup
Frappe
Easy setup, built on the frappe framework (https://github.com/frappe/lms).
- Dark mode :smiley-face:
- There is the abilty to add in programming language assessments :party:
- no arm images :/
Unsplash for API development
Setup:
# Build the custom image with:
export APPS_JSON_BASE64=$(base64 -w 0 apps.json)
# content of app.json
#[
# {
# "url": "https://github.com/frappe/lms",
# "branch": "develop"
# }
#]
# build the image
docker build --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe --build-arg=FRAPPE_BRANCH=version-15 --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 --tag=custom:15 --file=images/layered/Containerfile .
# create the compose spec
docker compose --env-file example.env -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml -f overrides/compose.noproxy.yaml config > compose.custom.yaml
# Add in the pangolin network & replace amd64 with arm64
# bring up the app
docker compose -f compose.custom.yaml up -d --pull never
# Create a new project at the desired subdomain
docker compose exec backend bench new-site learn.kenyon.app --mariadb-user-host-login-scope='172.%.%.%'
# Install lms (which was baked into the base image)
docker compose exec backend bench --site learn.kenyon.app install-app lms
Sources: https://github.com/frappe/lms https://github.com/frappe/frappe_docker/blob/main/docs/getting-started.md
Docs: https://docs.frappe.io/learning/introduction
may be able to add resend functionality:
- Seems like it’s more to separate input / output settings: https://github.com/rtCamp/frappe-email-send-override/blob/main/README.md
- TBD https://github.com/NagariaHussain/resend_integration/tree/develop
Connect with pangolin (e.g. change the network to pangolin).
This is a rabbit hole - since the app still uses an nginx reverse proxy. I am unsure how to go about getting the server to resolve correctly when using traefik supplied by pangolin. Basically the request hits nginx, but it will respond with a 404 on any resources due to an invalid host (e.g. learn.kenyon.app does not exist).
I also went through the whole process of creating our own docker file using the overrides. There is supposidly a pwd.yml file tin the repository that has a good minimal setup and uses the host frontend.
This option is the most appropriate due to the balance of support, complexity to deploy, and extensibility for in-app programming evaluation.
Adding an email account - need to set the settings for the smtp server (e.g. smtp.resend.com) with the password being the API key. For SSL - need to use port 465.
Google drive integration: https://docs.frappe.io/framework/user/en/integration/google_drive (This didn’t seem to be applicable)
More info on adding a lesson: https://docs.frappelms.com/course-creation/add-a-lesson.html
- You can insert a google slides presentation into a lesson by copying the sharable link (permissions likely need to be open).
There’s a set of open standards for elearning: scorm. The Frappe LMS supports importing as this format, which should ease the burden of porting courses from other platforms. Frappe has a CSV or XLSX import and export. (There is also a full-on backup which can be run weekly to back up course content)
If you configure the Frappe desk to use the google api for backing up the data (needed to add some an http redirect uri) - likely due to routing the traffic through pangolin.
- update the API key (restricted to google drive api access)
- update the test users of the application (cannot publish while there is a http redirect)
- authorize the google drive access in the Frappe
/app/google-drivesettings
Files are then periodically backed-up to the google drive, and can be restored with the bench restore api:
https://docs.frappe.io/framework/user/en/bench/reference/restore
Summary
Overall, the solution that best fit my use case is frappe - the user management is not too cumbersome, the docker setup was sufficient for the purposes of hosting small learning management system, although it took a minute to sift through the content to determine what the “advised” method of setting up the app should be. After adding it into my pangolin network, everything is running smoothly. resend works great for sending out service emails for purposes such as account creation.