Signal & Context
← Back to the reading room

Infrastructure

A small server changes the architecture

Three publications do not need three always-on application stacks. Start with the resources you can actually measure.

On this page

The deployment problem we actually had

We wanted three publications with one editorial workflow, while keeping existing applications on a small shared server. This article records the arrangement we chose for these sites. It is a deployment case, not a claim that every CMS should be static or that a small VPS can handle unlimited traffic.

A retained snapshot from October 28, 2026 measured two CPU cores, 1,741 MiB of total memory, 520 MiB available and 1,033 MiB of occupied swap on the website host. The older static release occupied about 16 MiB on disk and added no separate always-on application worker for each publication. Those numbers describe that observation and release. Available memory was not reserved capacity; occupied swap alone did not establish active swapping or a current outage.

Separate a publishing system from a reading system

We kept Wagtail and its editorial database private, built finished pages on the development machine, and served the exported files through the web server already in use. The browser handles directory filtering and the cost calculator. Suggestions and corrections use a separate small receiver; they do not expose the authoring database or publish submissions automatically.

  1. Publishing: private authoring → static build → checked release → existing web server → reader.
  2. Suggestions: reader suggestion → separate review queue → later editorial decision.

This division avoids starting three copies of an application server merely to deliver three brands. It also creates a tradeoff: a CMS edit needs a successful export and publication step before readers see it. Account-based personalization, private paid content and live full-text search would require additional design; this static release does not supply them.

What we verified, and what that proves

On November 6, 2026 we rechecked the retained production artifact: 836 payload files matched their manifest sizes and SHA-256 hashes. It contained 77 HTML pages for 74 entries, including policies and intake pages. A separate HTTP readback of all 77 public HTML routes returned 200 and matched those artifact bytes. These checks establish which files were delivered. They do not establish factual accuracy, peak concurrency or visitor experience in every region.

The sanitized architecture evidence JSON records the dated resource snapshot, artifact identity and limits. It omits host addresses, credentials, private paths and database contents. The historical disk reading is deliberately separate from the current file count.

A release procedure with a clear failure boundary

  1. Read the active version first. Identify the release currently serving readers and preserve independent changes, including verification tags and advertising choices.
  2. Build away from the shared host. Export only publishable content. Keep the CMS database, keys and draft material out of the web artifact.
  3. Check the candidate as a package. Verify its file inventory, canonical URLs, links and intended indexing state. Exercise its existing search, forms and calculator separately.
  4. Switch the version pointer atomically. Keep a recoverable predecessor. If another release has appeared since the initial read, stop and reconcile it instead of replacing it.
  5. Read the public result back. Match representative bytes and test the affected interaction. A successful upload is an intermediate result.

When this decision should change

Move the editor onto dedicated always-available infrastructure when editorial availability requires it, or add a dynamic service when a real reader task requires server state. First measure that service under a representative workload and retain headroom for the applications already running. For this project, finished files were enough for reading, while a narrow receiver covered submissions. That is the useful boundary: add a process for a demonstrated need, then test the process rather than inferring its cost from the framework name.

Suggest a correction

Continue reading