Chapter 18 of 20 · 3 min · 90% through
Running it
Two ways to run the same thing
The editing application runs either directly on my machine or inside a container, and the same code serves both. Which one is running changes configuration, never behaviour.
Directly is the quick path — one command, and the editor and the live preview come up together.
The container is the complete path, and it is what I actually use.
What the container adds
Every dependency, present. Deck conversion needs a document renderer and a page rasteriser, plus the fonts they substitute badly without. The browser tier of the test suite needs a browser. On a bare machine those are things you have to install and keep working; in the container image they are simply there.
That difference is visible in the product rather than hidden in the tooling. Drop a presentation onto a deck in the container and it becomes slides. Do it on a machine without the renderers and the editor says so plainly — naming what is missing and how to get it — rather than failing somewhere deep in a pipeline.
Tests that mean the same thing everywhere. “All tests pass” should not depend on what happens to be installed on one laptop. The test image carries its own browser, so the browser-driven tiers run identically wherever they run.
Isolation. The editing application can publish to a live site. Running it in a container with an explicit list of what it can reach is a better default than running it directly with access to everything.
What is shared and what is not
The repository itself is mounted into the container, so edits land on the host and stay in version control. That is the whole point — the container is the environment, not the storage.
A few things are deliberately not shared. The installed dependencies stay inside the container, because they are built for its operating system and would be wrong on the host. The build cache and build output are not shared either: both record absolute paths, and two processes writing one cache corrupt each other in a way that surfaces as an empty article list rather than as a cache error — which is a genuinely miserable hour of debugging to be spared.
Ports, bound to the loopback
The container publishes its ports to the local machine only, never to the network.
Inside, the application binds broadly, because a container’s own loopback is not reachable from the host and binding narrowly would make it unreachable. The restriction to “this machine only” is applied at the boundary instead.
The distinction matters because getting it backwards produces either an unreachable editor or one exposed to the local network, and the second failure is silent.
The health check
The container reports whether the editing application is answering.
Worth one note: locked is a healthy state. The application starts locked by design, so a health check that required it to be unlocked would report a correctly-behaving system as broken.
Bringing the whole thing up
One command brings up the editor, the live preview and the connected interface together. Another runs the full test suite inside the same image.
That is the practical payoff of containerising a personal project — not scalability, which is irrelevant here, but the fact that the thing either runs or does not, with no “works on my machine” in between.