Stormy Sailors Crest
Think Like A Captain. Play Like A Pirate

Building the Captain’s Bridge: How StormyOS Came to Life

The Beginning

When I first started putting StormyOS together, the idea was simple: build a full-screen dashboard for the television that could show useful information at a glance.

As usual, “simple” lasted about five minutes.

What began as a Raspberry Pi connected to a TV gradually turned into a proper little bridge system—part status board, part weather station, part race desk, part ship’s log, and part home for Ember, the ship’s fox.

More Than a Dashboard

The hardware itself is modest: a Raspberry Pi 4 driving a 1920×1080 television.

The interesting part is everything happening behind the screen.

StormyOS runs as a collection of isolated services. The dashboard and API live in containers, nginx serves the frontend, and the whole system is deliberately kept on the local network.

The firewall permits only SSH and HTTP from the LAN. The API runs as an unprivileged user with a read-only filesystem, no Docker socket, and its Linux capabilities removed.

That might sound excessive for something attached to a television.

But one of the goals from the beginning was to build this properly rather than create another fragile collection of scripts that works brilliantly until six months later when nobody—including the fellow who wrote it—can remember how the bloody thing works.

Stations of the Bridge

Rather than presenting one enormous dashboard, StormyOS rotates through individual stations.

Each station has a particular job while sharing the same navy-and-brass Bridge design.

Engineering Station

Engineering keeps watch over the Raspberry Pi itself.

It monitors CPU utilization, temperature, memory, disk space, container health, and power and throttling conditions.

The idea isn’t simply to display numbers. The station should make it immediately apparent when something aboard the Bridge needs attention.

Weather Station

Weather became considerably more interesting than I originally expected.

StormyOS now uses official Canadian weather information from Environment and Climate Change Canada, presenting current conditions and forecasts in something closer to a ship’s weather station than a generic web weather widget.

Temperature and conditions take centre stage, accompanied by humidity, pressure, wind, forecast information, and official weather watches and warnings.

Wind gets particularly nautical treatment, because if you’re going to build a Captain’s Bridge, you might as well commit to the bit.

Race Station

Naturally, there had to be Formula 1.

Race Station handles Grand Prix schedules, converts session times into Edmonton local time, distinguishes between conventional and sprint weekends, and counts down to upcoming sessions.

That station is still undergoing refinement.

Which is the polite naval way of saying it is currently back alongside with engineers crawling through it.

Ember Station

And then there’s Ember.

Ember is the ship’s fox, Morale Officer, and Keeper of the Warm Berth.

Her station combines her portrait, current disposition, shipboard duties, a short log entry, outside weather conditions, and something known as the Ember Advisory.

For example, when thunderstorms threaten Edmonton, StormyOS may issue:

UNDER-BED CONDITIONS LIKELY

This particular forecasting model has been extensively field-tested.

Its accuracy is exceptional.

Cookie negotiations remain possible.

A Captain’s Log That Became an Actual Log

The Captain’s Log originally wasn’t much of a logbook.

Its entries were embedded directly into the dashboard’s HTML.

That meant changing an entry required editing source code, rebuilding the frontend, creating another immutable StormyOS release, deploying it, and reloading the kiosk.

That is an admirably complicated method of writing a paragraph.

So Captain’s Log became live runtime data instead.

Entries now live in a validated, host-owned JSON log. Updates are transferred securely over SSH, validated before activation, and installed atomically so the dashboard never sees a half-written logbook.

Once accepted, the new entry appears through the Bridge’s normal refresh cycle.

No frontend rebuild.

No new StormyOS release.

No container restart.

No kiosk reload.

More importantly, the operational Bridge remains independent of anything outside the ship.

From the Bridge to the Ship’s Log

The next logical step was connecting Captain’s Log to the Stormy Sailors website.

But I didn’t want the Bridge automatically throwing everything I wrote onto the public Internet.

The distinction matters.

Captain’s Log belongs to the Bridge.

The Ship’s Log is the public record.

So publishing is deliberately separate and explicit.

A selected Captain’s Log entry can be reviewed and then published to WordPress using a Mac-side publishing tool. The WordPress credentials never need to live inside the kiosk or its API, and the website never becomes a dependency of StormyOS.

If the website disappears over the horizon, the Bridge keeps sailing.

That’s exactly how I want it.

The Work Nobody Sees

One of the more interesting lessons from building StormyOS has been just how much of the work has nothing to do with flashy features.

A surprising amount of development has gone into things such as:

  • deterministic frontend builds;
  • immutable releases;
  • automatic backups and rollback procedures;
  • container isolation;
  • safe rendering of untrusted text;
  • malformed-data handling;
  • stale and offline states;
  • exact 1920×1080 rendering tests;
  • ensuring one failed data source cannot sink the rest of the Bridge.

There have also been some wonderfully irritating real-world problems.

The television, for example, decided its preferred display mode was 3840×2160 at 30 Hz when what I actually wanted was 1920×1080 at 60 Hz.

An early attempt at the dedicated kiosk environment therefore went sideways and was rolled back.

There have been tiny fonts, truncated Captain’s Log entries, stale telemetry, layouts that looked beautiful on a computer monitor and terrible eight feet away on the actual television, and the occasional feature that passed every automated test only to make me look at the screen and say:

“No. That looks like shit.”

Which led to one of the more useful engineering rules aboard StormyOS.

A test saying GREEN is useful. The Captain looking at the television and saying GREEN is final.

The Voyage Continues

StormyOS isn’t finished.

I’m not sure it ever really will be.

The Formula 1 Race Station needs more work. The Ship’s Log is evolving. There are other stations and integrations rattling around in my head, and I’m reasonably certain Ember will eventually demand additional privileges.

But somewhere along the way, the project stopped feeling like a Raspberry Pi displaying a webpage on a television.

It developed a character of its own.

It started feeling like a bridge.

And that was the point.

All stations GREEN. The voyage continues.

Captain Stormy
Stormy Sailors Maker Lab