paint-brush
This Open Source Tool Lets You Build Your Own LMS on Kubernetesby@ainababs0
192 reads

This Open Source Tool Lets You Build Your Own LMS on Kubernetes

by Adeyemi AinaMarch 5th, 2025
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

In today’s digital landscape, managing student classes, assignments, and research tools effectively requires a robust and flexible Learning Management System (LMS) [Canvas LMS] has emerged as a leading open-source platform, offering comprehensive features that cater to the needs of both educators and learners.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - This Open Source Tool Lets You Build Your Own  LMS on Kubernetes
Adeyemi Aina HackerNoon profile picture
0-item
1-item

In today’s digital landscape, managing student classes, assignments, and research tools effectively requires a robust and flexible Learning Management System (LMS). Canvas LMS has emerged as a leading open-source platform, offering comprehensive features that cater to the needs of both educators and learners. Its modular design, extensive integration options, and support for modern standards like Learning Tools Interoperability (LTI) make it a powerful choice.

Canvas by Instructure

Canvas LMS is versatile and can be deployed for various purposes, including small group or organizational use, research data collection, and development projects like Caliper analytics. It also supports interoperability with different LTI versions. This guide is particularly focused on individuals setting up their own Canvas instance, who need access to the Canvas admin panel or dashboard for development and building LTI 1.3 support for learning tools.


However, there is a notable challenge in the adoption of LTI 1.3 by institutions and individuals. Public Canvas instances, such as those hosted by Instructure, do not support LTI 1.3, which is the latest version enabling advanced integrations and tools. For educators, researchers, or developers seeking to leverage the full capabilities of LTI services, self-hosting Canvas LMS becomes essential.


In this article, I’ll walk you through deploying Canvas LMS on a Kubernetes cluster. Whether you’re managing a small educational organization or working on research and development, this guide will help you navigate the challenges of deploying a large-scale application like Canvas. You’ll gain the knowledge needed to set up Canvas, troubleshoot common issues, and leverage its powerful features, including Single Sign-On security with LTI 1.3. LTI 1.3 has become the industry standard for OAuth 2.0 security and Single Sign-On, used by platforms like LinkedIn Learning, which essentially serves as LinkedIn’s own Learning Management System.

1. Preparing for Deployment

Before diving into the deployment process, it’s essential to set up the foundational components. Start by cloning the Canvas LMS repository and configuring the required Docker and Docker Compose files to suit your needs.

1.1 Clone the Canvas LMS Repository

To begin, clone the Canvas LMS GitHub repository and switch to the prod branch. The production branch is optimized for deployment and contains the necessary files for setting up Canvas in a production environment. Run the following commands:

git clone https://github.com/instructure/canvas-lms.git
cd canvas-lms
git checkout prod

1.2 Focus on Docker Files and Configuration

Canvas LMS supports Docker-based deployment, making it easier to containerize and orchestrate the application and its dependencies. Inside the repository, you’ll find:

1.2.1 Dockerfile

  • This file defines the build instructions for the Canvas web application container.
  • Review the FROM instructure/ruby-passenger base image and configurations for NGINX, Passenger, and Ruby.

1.2.2 docker-compose.yml

  • This file defines the multi-container setup for local testing or lightweight deployments.
  • Key services include:
  • web → The Canvas web application.
  • redis → Caching service.
  • postgres → Database.

1.2.3 Local Build

  • You can try a local build on your computer. Check out this quick start guide for more details.
  • After launching the containers, ensure the database is migrated and seeded with default data using the rakecommands.
  • Now you should access Canvas locally, now let’s move to deploying on Kubernetes.

2. Kubernetes

Kubernetes is an Orchestrating platform for containerized applications, basically applications packaged in a container, in which the ned user needs not to worry about environments, packages, versions etc, as name says the application can easily run on a container on any enviorment. Kuberntes provides a distributed cluster to easily orchestrate the containers and application mostly have some kind of distributed architecture or microservice architecture. so Kubernetes facilitates both configuration and automation of tht application’s ecosystem e.g an application might come with an API gateway as a standalone application, redis application for queue management, Database container, a file system and a user interface so this kind of distributed architecture there 5 different standalone application that interact with each other.


Here is a diagram that gives an overview of a Kubernetes environment.

Roadmap to mastering Kubernetes container orchaestration


Here also links to the overview of Kubernetes:

· Overview of Kubernetes

· What is Kubernetes

· Kubernetes overview & essential Reading

· Tutorial — Kubernetes

· Top posts about Kubernetes

3. Deploying the Kubernetes Cluster

To deploy Canvas LMS on Kubernetes, we leverage Kompose (conversion tool for docker compose to container orchastrators like Kubernetes) **to translate the existing docker-compose.yml into Kubernetes manifests. Kompose simplifies the process of converting Docker-based configurations into Kubernetes-native resources, such as:


· Deployments (Canvas Web, Redis, Postgres)

. Services (ClusterIP for internal services, LoadBalancer for public access)

. Persistent Volume Claims (PVCs)


After conversion, we can enhance these configurations to suit your production requirements. Carefully review the auto generated Kubernetes manifest by Kompose.

Overview of the deployment and microservices involved in the LMS application deployment


3.1 Creating the Canvas Deployment

The Canvas LMS application requires several Kubernetes components to function correctly: Deployments, Services, and Persistent Volumes. Translating Docker Compose with Kompose, run the following command to convert the docker-compose.yml file into Kubernetes YAML files:

kompose convert -f docker-compose.yml


This command generates several YAML files, including deployments, services, and persistent volume claims for all services defined in docker-compose.yml.

Sample Deployment for Canvas Web Application

Here’s an example of the deployment file for the Canvas web application:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: canvas-web
  labels:
    app: canvas-web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: canvas-web
  template:
    metadata:
      labels:
        app: canvas-web
    spec:
      containers:
        - name: canvas-web
          image: instructure/canvas-lms:latest
          ports:
            - containerPort: 3000
          env:
            - name: RAILS_ENV
              value: "production"
            - name: POSTGRES_PASSWORD
              value: "securepassword"
            - name: REDIS_URL
              value: "redis://redis:6379"
          volumeMounts:
            - name: canvas-storage
              mountPath: /usr/src/app/storage
      volumes:
        - name: canvas-storage
          persistentVolumeClaim:
            claimName: canvas-pvc


Also some Canvas requires persistent storage for its assets and configurations, Below is an example of a Persistent Volume Claim (PVC) configuration:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: canvas-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Exposing the Canvas Service

The web application is exposed via a Kubernetes service, which routes traffic to the Canvas deployment. Depending on your cluster’s configuration, you can use a ClusterIP, NodePort, or LoadBalancer type.


Here’s an example of the Service definition:

apiVersion: v1
kind: Service
metadata:
  name: canvas-web
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 3000
  selector:
    app: canvas-web


This configuration ensures that the Canvas web application is accessible over port 80 via an external load balancer.

Ingress Configuration

For production setups, we recommend using an NGINX Ingress Controller to route domain-based traffic to Canvas LMS. Here’s an example Ingress configuration:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canvas-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: canvas.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: canvas-web
                port:
                  number: 80

I’ll pause here to keep this article concise, but I’ll continue with common issues you might encounter when deploying a Canvas instance.

Challenges Encountered and How I resolved Them

  • Cloning the Canvas Repository


    Clone the official Canvas LMS repository from GitHub. The prod branch is the most stable production-ready version of Canvas LMS. git clone https://github.com/instructure/canvas-lms.git cd canvas-lms


    git checkout prod
    


  • Preparing the Configuration Files


    Canvas relies on various configuration files to define its database, Redis, and email settings. Copy the example configurations and modify them as needed

    cp config/database.yml.example config/database.yml cp config/outgoing_mail.yml.example config/outgoing_mail.yml
    


  • 502 Bad Gateway (NGINX) Cause: The web service is not listening on the expected port.


    Solution: Ensure that the service target port matches the container’s exposed port (3000 in our case).

    kubectl logs <web-pod-name> kubectl logs canvas-web
    


  • 503 Service Unavailable Cause: The service does not have available endpoints.


    Solution: Ensure the pods are running and correctly labeled.

    kubectl get pods kubectl describe service canvas-web-service
    



  • Database Connection Errors Cause: Incorrect credentials or network issues.


    Solution: Check the DATABASE_URL environment variable in the deployment.


  • Missing Assets or Broken UI Cause: Asset compilation was not performed.


    Solution: Run asset precompilation in the container:

    kubectl exec -it <web-pod> -- bash cd /usr/src/app RAILS_ENV=production bundle exec rake assets:precompile
    


  • Permission Errors (Protected Directories in the Container)


    Cause: Some files in /usr/src/app were owned by root, preventing docker user access.

    Fix: Modify Dockerfile and Dockerfile.production to update ownership:

    USER root RUN chown -R docker:docker /usr/src/app USER docker
    


  • Job Pods Keep Failing

    Cause: Insufficient memory or missing dependencies.

    Fix: Allocate more resources and check logs.


    kubectl logs jobs-pod
    

Conclusion

Deploying Canvas LMS on Kubernetes empowers organizations, researchers, and educators with full control over their learning management systems. Whether you’re a small organization looking to self-host an LMS for assessments, assignments, and structured coursework, this setup could be an ideal solution for your users.


This guide provides valuable insights, covering:

  • Setting up Canvas from the GitHub repository
  • Using Kompose to convert Docker Compose to Kubernetes
  • Deploying services, configuring ingress, and setting up persistent storage
  • Troubleshooting common Kubernetes and Canvas issues (Debugging 502, 503 errors, and permission issues)


With this setup, educators, researchers, and developers can self-host Canvas LMS, enabling LTI 1.3 features and efficiently managing learning environments. I’ve also included Kubernetes manifests in the Canvas LMS K8s repository here. Feel free to reach out if you encounter any issues!