Apache, Passenger, and the environment

This is a quick note on building an Apache+Passenger+Ruby 2.4 environment on RHEL7, with an explanation of some odd path issues with libraries and how to resolve them for both regular users and system users.

We’re building a RedHat Enterprise (RHEL) 7 server with Ruby 2.4. We use Passenger to route traffic from Apache to the rails applications hosted on the box. RHEL7, by default, ships with Ruby 2.0.0-p684, which is outdated. To get up to Ruby 2.4, we have to add the software collections repository and then make a few configuration changes.

We start by installing a few packages. I found that we needed three base Ruby packages, plus Passenger:

Read More

Catapulting rocks

Last summer I did a series of posts in conjunction with a talk I gave at WPCampus on Lafayette’s WordPress deployment methodology. At the time the missing piece was a truly automated deployment. We implemented that at the end of August, but I never got around to writing it up until now. We retained our Capistrano methodology, but had GitLab execute the deployment from a container.

Containing Capistrano

In Rolling rocks downhill I described how we used Capistrano to deploy WordPress. The simplest way to automate the deployment and take the local developer out of the picture would be to have GitLab run the Capistrano deployment instead. This requires a few things:

Read More

Deploying MediaWiki with Capistrano

I’ve written at length about how we deploy WordPress with Composer and Capistrano. This week I’m going to write about how I adapted that workflow for our MediaWiki environments.

We have a couple MediaWiki environments which we manage on behalf of the campus community. The first thing I discovered was that our preferred approach–installing core with a git submodule and extensions with Composer–wasn’t viable. Beginning with MediaWiki 1.26.2 the core product ships with its own Composer dependencies, and extensions may choose to define dependencies of their own. The MediaWiki team supports this model with the composer-merge-plugin, which can combine the core and extension composer.json files on installation. When I attempted to overlay our extensions-as-composer-dependencies model on that environment it broke, and hard.

Instead, I fell back on the older model of nested git submodules. The core code is managed in an integration repository, and each extension is added to that repository as a submodule. The Capistrano git submodule gem handles this situation cleanly. For the extension composer dependencies, I defined a composer.local.json file for each project and added it to the shared files on the web server. In this example, I’m adding support for the SyntaxHighlight extension:

Read More

No, that's not it

This is a story of how a log file that got too large degraded a production system for a couple days. It illustrates what happens if you dive into a problem without stepping back and asking basic questions.

We use Redmine as an issue tracking/project management platform. It has the capability to ingest emails from standard input. Late last week, we realized that this feature had stopped working. What followed was a lot of time in the weeds which could have been avoided if I’d just stopped to work the problem.

Bouncy bouncy

Read More

Running Moodle CI tests in GitLab

I maintain about a dozen plugins in the Moodle plugins repository. I use Moodlerooms’ moodle-plugin-ci project to test all of them on Travis CI. It’s a fantastic tool and rely heavily on it.

This fall I’ve been working on a plugin which, because of various hooks into Lafayette’s internal infrastructure, I’m not releasing publicly. I’d still like to test it in the usual way, so I decided to run the tests on our internal GitLab infrastructure.

Building a container

Read More

Implementing a course archiving strategy in Moodle

A course archiving strategy is the white whale of higher education. I can remember being part of discussions a decade ago about how to keep a Moodle instance at a manageable size while preserving information. There were two challenges: come up with a policy that faculty could support, and execute a reasonable technical implementation of that policy. In this post I’ll discuss the tools we built to implement our chosen policy.

Policy

The policy we crafted with faculty input is straightforward:

Read More

Measuring activity in Moodle

It’s a simple question with a complex answer: in a given academic term, what percentage of our Moodle courses are “active” (used by a faculty member in the teaching of their course). We have to start by figuring out what counts as a “course” in a term, and then come up with an inclusive measurement of activity.

Courses

The basic unit in Moodle is the course. We use the Banner/Luminis Message Broker plugin to create a course for each section of each course which is taught for a given term at Lafayette. Each of these courses has an idnumber which corresponds to the section’s CRN. An exception is crosslisted courses; the LMB plugin creates a merged course with a special idnumber.

Read More

Pick a date, any date

Moodle 3.2 introduced the concept of end dates for courses. Moodle 3.3 added a new Course Overview block which uses end dates to determinate whether a course is in progress, in the past, or in the future. This is pretty great, unless you’re in the following situation:

  • Your school has five years worth of courses
  • Those courses don’t have end dates

Congratulations—you now have five years of courses in progress. Your faculty will have five pages worth of past courses on the Course Overview block! That’s probably undesirable. To avoid it, I’m writing a plugin that lets an administrator set course start and end dates at the category level. While working on it, I ran an interesting edge case with Behat acceptance tests, reminding me that you’d best treat Behat like it's a real user.

Read More

WordPress and partial content

Eighteen months ago we had an anomalous problem where video playback didn’t work on some, but not all, of our WordPress multisites. Videos wouldn’t play, or would play but wouldn’t seek. The problem was confined to local uploads embedded in a page. Videos from YouTube played fine; if you viewed the video directly playback worked as expected.

The problem turned out to be long-standing issue with how ms-files.php served up files from pre-WordPress 3.5 multisites. Solutions had floated around for years. Our problem was describing the problem with enough specificity to actually find the right solution.

Past is prologue

Read More