Skip to content

Instantly share code, notes, and snippets.

@adeel-raza
Last active August 8, 2023 17:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adeel-raza/4eb1dae869c393431df0afda6db6987d to your computer and use it in GitHub Desktop.
Save adeel-raza/4eb1dae869c393431df0afda6db6987d to your computer and use it in GitHub Desktop.
Self Host and Install Canvas LMS on Ubuntu Server in 2023
Canvas is a powerful open-source LMS that can be self-hosted on your own server. This is a detailed guide to help you Install Canvas LMS on Ubuntu using the Apache web server and enabling SSL for secure communication. Let's get started!
Caution: Before proceeding, make sure you have administrative access to your Ubuntu server by running "sudo su" and have basic knowledge of command-line operations. Canvas requires Ubuntu 20.04 LTS and a server with at least 8GB RAM. The steps below are quite technical and require a server administrator.
If it's technically challenging for you, allow us to help you set up with our Canvas Installation Service.
Step 1: Create a PostgreSQL user and databases for Canvas
Once you execute this command, it will ask for your server password and then, your canvas PostgreSQL password. Please note the later one as it will be used when we will edit the canvas database config file.
sudo apt-get install postgresql-12; sudo -u postgres createuser canvas --no-createdb --no-superuser --no-createrole --pwprompt; sudo -u postgres createdb canvas_production --owner=canvas; sudo -u postgres createdb canvas_development --owner=canvas; sudo -u postgres createuser $USER; sudo -u postgres psql -c "alter user $USER with superuser" postgres;
Step 2: Installing Git, Ruby, Node.js, and Yarn
sudo apt-get install git-core; sudo apt-get install software-properties-common; sudo add-apt-repository ppa:instructure/ruby; sudo apt-get update; sudo apt-get install ruby3.1 ruby3.1-dev zlib1g-dev libxml2-dev libsqlite3-dev postgresql libpq-dev libxmlsec1-dev libidn11-dev curl make g++; curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -; sudo apt-get install -y nodejs; sudo npm install -g npm@latest; curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.19.1;
Step 3: Cloning and Install Canvas LMS
We will install Canvas in your current user home directory so that there are no permission issues later on and the user is able to access the files.
current_user=$(whoami); new_directory="/home/$current_user/"; mkdir -p "$new_directory"; sudo chown "$current_user":"$current_user" "$new_directory"; cd "$new_directory"; git clone https://github.com/instructure/canvas-lms.git canvas; cd canvas; git checkout prod; for config in amazon_s3 database delayed_jobs domain file_store outgoing_mail security external_migration; do cp config/$config.yml.example config/$config.yml; done
Step 4: Configuring Database, Outgoing Mail and Domain Settings
Set your Database credentials in this step, keep everything as it is, and just set the password to the value you entered in Step 1;
Note: When you open a file with nano command then press ctrl + x then Y to save the changes to the file.
cp config/database.yml.example config/database.yml; nano config/database.yml;
Set the dynamic settings correctly for LTI external tool integrations to work properly.
cp config/dynamic_settings.yml.example config/dynamic_settings.yml; nano config/dynamic_settings.yml;
Make sure you replace development with production at the top in the dynamic_settings.yml file
production:
# tree
Set your SMTP mail server details for emails to work on your Canvas LMS. See this guide to learn how to get your SMTP details for Gmail.​
cp config/outgoing_mail.yml.example config/outgoing_mail.yml; nano config/outgoing_mail.yml;
Set your domain name under Production -> domain. This should be the domain that is pointed to your server IP address. If you are not sure how to do this see this guide as an example.
cp config/domain.yml.example config/domain.yml; nano config/domain.yml;
Insert a randomized string of at least 20 characters in production -> encryption_key & set your own domain name in production -> lti_iss: '{domain_name}'. Make sure the domain name is properly set as this is required for LTI external tools to work properly on your Canvas.
cp config/security.yml.example config/security.yml; nano config/security.yml;
Your security.yml should look something like this,
production: &default
# replace this with a random string of at least 20 characters
encryption_key: daedd3a131ddd8988b14f6e4e01039c93cfa0160
lti_iss: '{domain_name}'
Step 5: Installing Dependencies and Compiling Assets
sudo gem install bundler --version 2.3.26; bundle config set --local path vendor/bundle; bundle install; sudo gem update strscan; yarn install; mv db/migrate/20210823222355_change_immersive_reader_allowed_on_to_on.rb .; mv db/migrate/20210812210129_add_singleton_column.rb db/migrate/20111111214311_add_singleton_column.rb; yarn gulp rev; RAILS_ENV=production bundle exec rake db:initial_setup; mv 20210823222355_change_immersive_reader_allowed_on_to_on.rb db/migrate/.; RAILS_ENV=production bundle exec rake db:migrate; mkdir -p log tmp/pids public/assets app/stylesheets/brandable_css_brands; touch app/stylesheets/_brandable_variables_defaults_autogenerated.scss Gemfile.lock log/production.log; RAILS_ENV=production bundle exec rake canvas:compile_assets;
Step 6: Installing and Configuring Apache
sudo apt-get install apache2; sudo apt-get install -y dirmngr gnupg apt-transport-https ca-certificates; sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7; sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger focal main > /etc/apt/sources.list.d/passenger.list'; sudo apt-get update; sudo apt-get install -y libapache2-mod-passenger; sudo a2enmod rewrite; sudo a2enmod passenger; sudo a2enmod ssl; sudo nano /etc/apache2/mods-available/passenger.conf;
Now, you have to add your server user in the config file. If you are not sure what it is then run whoami command to find out and add the user in passenger.conf file
PassengerDefaultUser {your_user_here} PassengerStartTimeout 180
If you want to enable error reporting until the installation is complete so you could view any errors during the process then you can also add the following line in the same file. Please make sure you comment out this line if everything goes well and you are in production mode.
PassengerFriendlyErrorPages On
In the next steps, we will be using these 2 placeholders {server_user} & {domain_name}. Please make sure you replace these with your actual values before executing the commands.
Step 7: Obtain SSL Certificate For Your Domain
Canvas requires a valid & verified SSL certificate to be installed for your domain, please note that self signed cert will not work. We will use Lets Encrypt to get a free certificate and make it auto-renew so it does not expire after the 3-month period.
A) Install Certbot:
sudo apt update; sudo apt install certbot;
B) Install certbot plugin for Apache:
# Install Certbot for Apache
sudo apt install python3-certbot-apache
# Install Certbot for Nginx
#sudo apt install certbot python3-certbot-nginx
C) Obtain the SSL Certificate: Once you execute the below command and follow the steps a SSL cert and private key will be generated on your server. Note the following 2 paths to enter in the next Step 8: Cert: /etc/letsencrypt/live/{your_domain}/fullchain.pem Key: /etc/letsencrypt/live/{your_domain}/privkey.pem
# For Apache
sudo certbot --apache -d {your_domain}
# For Nginx
sudo certbot --nginx
D) Automatic Renewal: Let's Encrypt SSL certificates are typically valid for 90 days. To automatically renew them, you can set up a cron job in the crontab as follows:
crontab -e
Add the below line once you've opened the crontab with the above command, save and exit.
0 0 * * * /usr/bin/certbot renew --quiet
Step 8: Configuring Virtual Hosts for Canvas
First, disable any Apache VirtualHosts you don't want running
sudo unlink /etc/apache2/sites-enabled/000-default.conf
Now we will create a Virtual host for our Canvas LMS Installation.
sudo nano /etc/apache2/sites-available/canvas.conf
Add the following configuration to canvas.conf:
<VirtualHost *:80>
ServerName {your_domain}
DocumentRoot /home/{server_user}/canvas/public
PassengerRuby /usr/bin/ruby3.1
PassengerAppEnv production
RailsEnv production
<Directory /home/{server_user}/canvas/public>
AllowOverride all
Options -MultiViews
Require all granted
</Directory>
</VirtualHost>
sudo nano /etc/apache2/sites-available/canvas-ssl.conf
Add the following configuration to canvas-ssl.conf: Set the paths for these 2 variables according to the value recived in Step 7: for cert and key
SSLCertificateFile and SSLCertificateKeyFile
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName {your_domain}
DocumentRoot /home/{server_user}/canvas/public
PassengerRuby /usr/bin/ruby3.1
PassengerAppEnv production
RailsEnv production
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/{your_domain}/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/{your_domain}/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
<Directory /home/{server_user}/canvas/public>
AllowOverride all
Options -MultiViews
Require all granted
</Directory>
</VirtualHost>
</IfModule>
sudo a2ensite canvas.org; sudo a2ensite canvas-ssl.org;
Step 9: Optimizing File Downloads (Optional)
you can optimize the downloading of files using the X-Sendfile header (X-Accel-Redirect in nginx). First make sure that apache has mod_xsendfile installed and enabled. For UBUNTU this can be done by following command:
sudo apt-get install libapache2-mod-xsendfile; nano config/environments/production-local.rb;
Add the following lines to production-local.rb:
# If you have mod_xsendfile enabled in Apache:
config.action_dispatch.x_sendfile_header = 'X-Sendfile'
# For nginx:
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
Step 10: Setup Automated jobs & Firewall Rules
sudo ln -s /home/{server_user}/canvas/script/canvas_init /etc/init.d/canvas_init; sudo update-rc.d canvas_init defaults; sudo /etc/init.d/canvas_init start; sudo ufw allow 80; sudo ufw allow 80/tcp; sudo ufw allow 443; sudo ufw allow 443/tcp; sudo ufw reload;
Step 11: Setup Redis in Cache Configuration (Required)
Some of the features of Canvas require Redis, such as OAuth2 which is needed for LTI external tools, so it's required that you setup Redis for caching.
Required version: redis 2.6.x or above.
sudo add-apt-repository ppa:chris-lea/redis-server; sudo apt-get update; sudo apt-get install redis-server; sudo systemctl start redis-server; sudo systemctl enable redis-server; sudo cp config/cache_store.yml.example config/cache_store.yml; sudo nano config/cache_store.yml;
Make sure the cache_store.yml file contains:
test:
cache_store: redis_cache_store
development:
cache_store: redis_cache_store
production:
cache_store: redis_cache_store
sudo cp config/redis.yml.example config/redis.yml; sudo nano config/redis.yml;
Make sure the redis.yml file contains:
production:
servers:
- redis://localhost
Step 12: Set Correct Permissions & ensure users can't read private Canvas files
This is a critical command that could cause irreversible damage if executed incorrectly. Before doing this make sure you are in your Canvas LMS installation directory. In this case, `/home/{server_user}/canvas`
current_user=$(whoami); sudo chown -R "$current_user":"$current_user" .; sudo find config/ -type f -exec chmod 400 {} +;
@adeel-raza
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment