Engine change at New Haven

Beginning with a round-trip to Brattleboro, Vermont, in March 2013 for HighEdWeb New England, I made at least one round-trip on the Vermonter every year between 2013 and 2017, and then two more in 2019. I’ve logged 3,033 miles since 2013. I’ve made a couple of firsts aboard it as well: my first trip east of New York on the Northeast Corridor, and my first trip east of Springfield on CSX’s Boston Subdivision.

The Vermonter makes a daily run from Washington, DC, to St. Albans, Vermont, just shy of the Canadian border. It uses Amtrak’s Northeast Corridor from Washington, DC, to New Haven, Connecticut (via New York City), then turns north to follow the Connecticut River through Springfield, Massachusetts, into Vermont. I’ve never been further north than Bellows Falls, Vermont; normally I don’t even take it into Vermont. I’ve also never taken it west of New York, not that there’s a reason to.

The Vermonter has some unusual features. Up until the end of 2014, it made a backup move at Palmer, east of Springfield, to continue north toward Vermont. This took a good twenty minutes as the Vermonter pulled past the crossing the connecting track, stopped, the crew manually threw a switch, then reversed direction. It’s a J-turn, but on a railroad. The state acquisition of the Connecticut River Line, completed at the end of 2014, eliminated this operation, though for good measure the Vermonter still backs in and out of Springfield Union Station.

Read More

Circling Deerfield Park

A man is a very small thing, and the night is very large and full of wonders

Lord DunsanyPlays of Gods and Men

I’m back visiting my parents in Mt. Pleasant, Michigan, where I grew up and spent the first 18 years of my life. Mt. Pleasant is a small place. Even now, the permanent population is about 26,000. Central Michigan University, when it’s in session, adds another 20,000. It’s not even 8 square miles. A man can walk from Pickard Road, at the northern edge, to Broomfield in the south, in under an hour. Growing up, it didn’t seem that way. I counted it as a major achievement when I first bicycled to the southern edge of CMU’s campus. As we get older the familiar shrinks even as the unfamiliar expands.

Deerfield Park is one of several parks on the Chippewa River, which runs through the county and city. It’s about five miles west of town, a stone’s throw though it didn’t seem that way once. It’s a little under two miles north-south and a little under a mile across at its widest point, though in that space are a multitude of trails, campsites, a generous sledding hill less dangerous than Mission Creek, and no fewer than four crossings of the river. In my memory, there was always a bridge that was hard to find, hidden away off the beaten path. Today, with clear skies and time to kill, I resolved to find all four bridges and settle the matter.

Read More

Apache and HTTP/2 on AWS

I’ve spent the last few months building up a generic highly-available EC2 stack for our various on-premises applications. We’re using Apache as the webserver on EC2 since that’s what we’re familiar with. An interesting wrinkle is that, out-of-the-box, cURL and Safari didn’t work with WordPress running on this stack. cURL would return this cryptic error message:

curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

Safari refused to render the page at all, with this equally (un)helpful message:

Read More

Using TLS-ALPN-01 on a Raspberry PI

I'll always read ALPN as Alpine

I run Nextcloud on my Raspberry PI and I have a certificate from Let’s Encrypt on it. I set this up a couple years ago with certbot and it’s been fine. I don’t expose port 80 in my environment so I’ve relied on the TLS-SNI-01 challenge using the certbot client which ships on Raspbian Jessie.

TLS-SNI-01 is now end-of-life because of security vulnerabilities so I needed to find an alternative. There are a couple different challenge methods available. Let’s Encrypt’s cerbot supports two:

Read More

Node on RHEL7

In August 2017 we implemented Swarthmore College’s PDF accessibility tool for Moodle. This required us to stand up a Node.js application, which was a new experience for us. Our environment was RHEL7, and our preferred web server Apache.

Application deployment

We followed our usual Capistrano principles for deploying the application. We created a simple project with all the Capistrano configuration and then mounted the Swarthmore project as a git submodule in a top-level directory named public. We configured the Capistrano npm module to use public as its working directory to ensure that the various node modules are installed on deployment.

Read More

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