Canvas LMS
Canvas Learning Management System
What is Canvas LMS?
Canvas LMS (Learning Management System) is an open-source online learning platform designed to help educators create, manage, and deliver courses online or in a blended learning environment. It provides tools for course management, communication, assessment, reporting, and integration with third-party applications.
Prerequisites
- Ubuntu Server 22.04
Dependencies
> sudo apt install -y git curl libssl-dev libreadline-dev zlib1g-dev \
autoconf bison build-essential libyaml-dev libreadline-dev \
libncurses5-dev libffi-dev libgdbm-dev zlib1g-dev \
libxml2-dev libsqlite3-dev postgresql libpq-dev \
libxmlsec1-dev libyaml-dev libidn11-dev make g++
User and Directory
> sudo adduser canvas
> sudo visudo
Copy the line under # User privilege specification
and duplicate it like this:
# User privilege specification
root ALL=(ALL:ALL) ALL
canvas ALL=(ALL:ALL) ALL
Create Canvas Installation Folder
> sudo mkdir -p /data
> sudo chown canvas:canvas /data
Checkout Git
> cd /data
> git clone https://github.com/instructure/canvas-lms.git canvas
> cd canvas
> git checkout prod
Install Ruby
Instructure Repo
> sudo apt install software-properties-common
> sudo add-apt-repository ppa:instructure/ruby
> sudo apt update
> sudo apt install -y ruby3.1 ruby3.1-dev zlib1g-dev libxml2-dev \
libsqlite3-dev libxmlsec1-dev libyaml-dev \
libidn11-dev curl make g++
Rbenv
- Switch to the
canvas
user and run the following commands:
> git clone https://github.com/rbenv/rbenv.git ~/.rbenv
> echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
> echo 'eval "$(rbenv init - bash)"' >> ~/.bashrc
> source ~/.bashrc
- Install
rbenv-build
plugin:
> git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
- Verify installation
> rbenv -v
- Install Ruby
> rbenv install 3.3.3
> rbenv global 3.3.3
Using Ruby
Check these commands first:
> which bundle
> which bundler
> which gem
> bundle config set --local path vendor/bundle
Install Node.js
apt
> curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
> sudo apt-get install nodejs
> sudo npm install -g npm@latest
NVM
> curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
> nvm install 22
> nvm use 22
NPM Mirror (optional)
> npm config set registry https://registry.npmmirror.com
Yarn
If the node.js was installed by apt
:
> sudo npm -g install yarn
Since we use NVM to manage Node.js, run the following command without sudo
:
> npm -g install yarn
Switch to the Canvas installation folder:
> yarn install
Canvas Configuration
> for config in amazon_s3 database vault_contents \
delayed_jobs domain file_store outgoing_mail security external_migration; \
do cp config/$config.yml.example config/$config.yml; done
Dynamic Settings Configuration
> cp config/dynamic_settings.yml.example config/dynamic_settings.yml
> nano config/dynamic_settings.yml
Database Configuration
If you want to use a remote RDS instance, make sure the database user has a high privilege role.
> cp config/database.yml.example config/database.yml
> nano config/database.yml
Security Configuration
> cp config/security.yml.example config/security.yml
> nano config/security.yml
Domain URL Configuration
> cp config/domain.yml.example config/domain.yml
> nano config/domain.yml
Outgoing Email Configuration
> cp config/outgoing_mail.yml.example config/outgoing_mail.yml
> nano config/outgoing_mail.yml
Replace example.com with your production domain
production:
domain: "example.com"
# whether this instance of canvas is served over ssl (https) or not
# defaults to true for production, false for test/development
ssl: true
# files_domain: "canvasfiles.example.com"
Delayed Jobs Configuration
> cp config/delayed_jobs.yml.example config/delayed_jobs.yml
> nano config/delayed_jobs.yml
The max_priority will split jobs by priority level.
production:
workers:
- queue: canvas_queue
workers: 2
max_priority: 10
- queue: canvas_queue
workers: 4
Database Migration
Gulp runs the rev task, which likely:
- Appends hash-based revisions to asset filenames.
- Updates references in your HTML, CSS, or JavaScript files.
- Prevents browser caching issues when assets are updated.
To fully understand what the rev task does, check the gulpfile.js in your project, especially where gulp-rev or similar plugins are used.
> yarn gulp rev
> RAILS_ENV=production bundle exec rake db:initial_setup
Generate Assets
> cd <your_canvas_root_folder>
> mkdir -p log tmp/pids public/assets app/stylesheets/brandable_css_brands
> touch app/stylesheets/_brandable_variables_defaults_autogenerated.scss
> touch Gemfile.lock
> sudo chown -R <canvas_user_name> config/environment.rb log tmp public/assets \
app/stylesheets/_brandable_variables_defaults_autogenerated.scss \
app/stylesheets/brandable_css_brands Gemfile.lock config.ru
> RAILS_ENV=production bundle exec rake canvas:compile_assets
> chown -R <canvas_user_name> public/dist/brandable_css
Permissions
> sudo chown <canvas_user_name> config/*.yml
> sudo chmod 400 config/*.yml
Apache & Passenger
You're now going to need to set up the webserver. We're going to use Apache and Passenger to serve the Canvas content. If you are on Debian/Ubuntu, you can do this quickly by following the instructions in Phusion's Deployment Guide:
Dependencies
> sudo apt install -y dirmngr gnupg apt-transport-https ca-certificates
Install Apache
> sudo apt install apache2
Install Passenger
> curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt | \
gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/phusion.gpg >/dev/null
> sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger \
$(lsb_release -cs) main > /etc/apt/sources.list.d/passenger.list'
Apache Modules
> sudo a2enmod rewrite
> sudo a2enmod passenger
> sudo a2enmod ssl
Passenger Configurations
Get the ruby
executable file by running the command which ruby
, then copy the returned path and update the configuration below:
> sudo nano /etc/apache2/mods-enabled/passenger.conf
Replace the copied path with the value of PassengerDefaultRuby
:
PassengerRoot /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini
PassengerDefaultRuby /usr/bin/passenger_free_ruby
PassengerInstanceRegistryDir /var/run/passenger-instreg
PassengerDefaultUser canvas
Apache VHost
<VirtualHost *:80>
ServerName canvas_domain
ServerAdmin your_email@domain.com
DocumentRoot /data/canvas/public
# Block /external_content/retrieve/oembed
RewriteCond %{REQUEST_URI} ^/external_content/retrieve/oembed
RewriteRule ^ - [F]
ErrorLog /var/log/apache2/canvas_errors.log
LogLevel warn
CustomLog /var/log/apache2/canvas_access.log combined
SetEnv RAILS_ENV production
PassengerEnabled on
PassengerPreloadBundler off
#XSendFile On
#XSendFilePath /data/canvas
<Directory /data/canvas/public>
Options All
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Redis Server
> sudo apt install -y redis-server
> redis-server --daemonize yes
> redis-cli ping
Canvas Scripts
Run the following command to get the GEM_HOME
path for the Canvas script if you are using rbenv
:
> gem env home
returns: /home/canvas/.rbenv/versions/3.3.3/lib/ruby/gems/3.3.0
Edit the canvas_init
file:
> nano <canvas_root_folder>/script/canvas_init
Uncomment the export GEM_HOME
and replace the path:
export GEM_HOME=/home/canvas/.rbenv/versions/3.3.3/lib/ruby/gems/3.3.0
Link script as a system startup script:
> sudo ln -s /data/canvas/script/canvas_init /etc/init.d/canvas_init
> sudo update-rc.d canvas_init defaults
> sudo /etc/init.d/canvas_init start
Logging
You can configure the Canvas logging.yaml file to use a database for logging:
production:
adapter: postgresql
encoding: utf8
database: canvas_production
host: localhost
username: canvas
password: password
timeout: 5000
queue:
adapter: postgresql
encoding: utf8
database: canvas_queue_production
host: localhost
username: canvas
password: password
timeout: 5000
Troubleshooting
The application encountered the following error: You have already activated stringio 3.1.1, but your Gemfile requires stringio 3.1.2. Since stringio is a default gem, you can either remove your dependency on it or try updating to a newer version of bundler that supports stringio as a default gem.
PassengerEnabled on
PassengerPreloadBundler off
Alternatively, try these:
> bundle update --bundler
> gem update stringio
> gem update --system
> bundle install