Skip to content

Update docs: Configuring with Apache & Phusion Passenger #12

@danielblignaut

Description

@danielblignaut

It's amazing that this is now required by canvas lms stable releases moving forward but there's a HUGE lack of documentation around production configuration or any configuration really.

On that note, for any lost souls, here's my implementation to get it working.

Disclaimer 1: I have not reviewed and made sure that all my steps are secure for a production environment
Disclaimer 2: This is not fully tested but course files insertion in canvas is now working and the API endpoints appear to be responding.

Requirements / Who this is for:

  • You have setup Canvas LMS using the open source version and have followed the production start
  • You aren't using Consul (this will still work for you but you won't update your dynamic_settings file, you will update consul settings instead... I am unfamiliar with Consul so Consul friends out there, please update this issue to help others)
  • You are using Phusion passeger
  • You are using Apache2
  • If you are using STATSD, please leave comment on how we can update this, I'm not

Instructions

Configure canvas core rce settings

First we need to configure canvas core's encryption strings for generating JWT tokens. Because our rce api server needs to be able to authenticate valid users, these config strings need to be shared with the rce api (we do this in the following step). We will also tell canvas core where our rce api server is hosted (in my case, its on the same server and url as the canvas install)

navigate to the dynamic_settings.yml config file. If you're using Consul, you proabbly need to do something else to update these values

cd /var/canvas/config
sudo nano dynamic_settings.yml

change "development" to "production" on line 7
change astringthatisactually32byteslong to a random string on line 14 (take note of this value as its later referenced as ECOSYSTEM_KEY_VALUE)
change astringthatisactually32byteslong to a random string on line 15 (take note of this value as its later referenced as ECOSYSTEM_SECRET_VALUE)
change rce.docker to yourcanvasdomain.com on line 31 (use whatever your domain is. dont include http /https)

a 32 byte long string is a string that is 32 characters long. Keep it alphanumeric. Use a random string generator.

update permisions for safety

sudo chown yourcanvasuser:yourcanvasuser dynamic_settings.yml
sudo chmod 400 dynamic_settings.yml

Install canvas-rce-api

We need to actually install this library / server onto our box and configure it.

ssh into your box, install canvas-rce-api wherever you would like (note the directory for that referenced as RCE_APP_DIRECTORY later on)

cd /var
git clone https://github.com/instructure/canvas-rce-api
cd canvas-rce-api
npm install
cp .env.example .env

You're now going to set the .env variables.

sudo nano .env

and update the values to below. I deleted CIPHER_PASSWORD completely. ECOSYSTEM_SECRET_VALUE and ECOSYSTEM_KEY_VALUE is referenced in the previous step as it is a core canvas project config value. Please enter their actual values below that you entered in the previous step, not ECOSYSTEM_SECRET_VALUE or ECOSYSTEM_KEY_VALUE

PORT=3001
NODE_ENV=production
STATSD_HOST=127.0.0.1
STATSD_PORT=8125
STATS_PREFIX=rceapi
ECOSYSTEM_SECRET=ECOSYSTEM_SECRET_VALUE
ECOSYSTEM_KEY=ECOSYSTEM_KEY_VALUE
CIPHER_PASSWORD=TEMP_PASSWORD

now lets update permissions again

cd ../
sudo chown -R superadminuser:superadminuser canvas-rce-api
sudo chmod -R 400 canvas-rce-api
sudo chown  canvasuser:canvasuser canvas-rce-api/.env
sudo chmod 400 canvas-rce-api/.env

Edit canvas-rce-api to run on phusion

Because we are making use of apache2 and phusion for our web server requests and SSL configuration, it makes sesnse to run this rce api inside phusion instead of standalone. To do that, we will need to update our nodejs code to check if phusion is installed, and if it is, let phusion manage what local port our application is running on. When we then configure our apache server and phusion settings in the next step, phusion will proxy all external requests meant for the rce server to the rce server on the local port that phusion has specified in our app :) lots of words.

cd /var/canvas-rce-api
sudo rm app.js
sudo nano app.js

and add the below js code to the new app.js file

const path = require('path');


require("dotenv").config({
        path: path.join(__dirname, '.env')
});


const container = require("./app/container");
const _application = require("./app/application");

module.exports = container.make(_application).listen();

save this file. then:

cd app
sudo rm application.js
sudo nano application.js

and add the below

"use strict";

const express = require("express");
const _stats = require("./middleware/stats");
const withMiddleware = require("./middleware");
const _env = require("./env");
const _routes = require("./routes");

if (typeof(PhusionPassenger) !== 'undefined') {
    PhusionPassenger.configure({ autoInstall: false });
}

function inject(provide) {
  return [_env, _routes, provide(console), provide(express()), _stats];
}

function init(env, routes, logger, app, stats) {
  app.use(stats.handle);
  withMiddleware(app, wrappedApp => routes(wrappedApp));
  const port = env.get("PORT", () => 3000);
  return {
    listen() {
        var server = null;
     if (typeof(PhusionPassenger) !== 'undefined') {
         logger.log('we are running in phusion');
         server = app.listen('passenger');
        } else {
                logger.log('we are running outside of phusion, on port ' + port);
                server = app.listen(port);
        }
      return server;
    }
  };
}

module.exports = { inject, init, singleton: true };

save file. You can see in the above, we are checking if phusion passenger is installed / running and if it is, we listen on 'passenger' otherwise we just use the port in our .env file.

Again, update permissions:

cd /var
sudo chown -R superadminuser:superadminuser canvas-rce-api
sudo chmod -R 400 canvas-rce-api
sudo chown  canvasuser:canvasuser canvas-rce-api/.env
sudo chmod 400 canvas-rce-api/.env

Update apache config & routes

now, this part is a bit of a mess. Basically from my findings, canvas has api endpoints on {yourdomain}/api .The issue here is that there is not specific subdirectory dedicated to the rce editor api routes, instead its a mix and match of rce server managed api routes and canvas core managed api routes. To get around this, I hardcoded all of the rce server api routes into a regular expression that we are going to add to our apache config below. Our code below basically says if apache matches a route to our regex, then instead of passing that route onto canvas core to manage, pass it to the rce server. Our code below also tells phusion passenger that we have an additional web app (our rce server)

cd /etc/apache2/sites-available
sudo nano canvas.conf

the canvas.conf is whatever you configured your site to be in the production start tutorial of the core canvas system.

In this file, you should see 1 or 2 root entries for VirtualHost. The first VirtualHost should be for port 80 (all http traffic). Before the closing tag for the http traffic, add the below

# These have been added for canvas-rce-api
       AliasMatch "^(/test_error|/test_jwt/api/announcements|/api/assignments|/api/discussions|/api/modules|/api/quizzes|/api/wikiPages|/api/files|/api/documents|/api/file|/api/folders|/api/images|/api/upload|/api/usage_rights|/api/flickr_search|/api/unsplash|/api/session|/api/youtube_title|/api/v1/services/kaltura_session|/api/media_objects)(.*)" /var/canvas-rce-api       
<LocationMatch "^(/test_error|/test_jwt/api/announcements|/api/assignments|/api/discussions|/api/modules|/api/quizzes|/api/wikiPages|/api/files|/api/documents|/api/file|/api/folders|/api/images|/api/upload|/api/usage_rights|/api/flickr_search|/api/unsplash|/api/session|/api/youtube_title|/api/v1/services/kaltura_session|/api/media_objects)(.*)">
                PassengerBaseURI /api
                PassengerAppRoot /var/canvas-rce-api

        </LocationMatch>
        <Directory /var/canvas-rce-api>
                Allow from all
                Options -MultiViews
                Require all granted
        </Directory>

Please update:

  • the second parameter of AliasMatch
  • PassengerAppRoot parameter
  • Directory parameter
    values to the root directory of your rce server install (mine is /var/canvas-rce-api

Please repeat the same process for your second VirtualHost entry if you have one (should be for ssl traffic).

restart apache! and you should be in business. There may be some mistyped commands above, please comment if this does not work for you and I can try assist however I'm no canvas evangelist so I probably won't be able to offer too much advice

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions