Atriumstatus

master9da7fa5

← all systems

Asset CDN

Operationalcritical@atrium/cdn

cdn.atriumad.com — client photos and reels on Hostinger shared hosting.

checked 3m ago· owner AtriumHost

Checks

Host reachable

The whole CDN is down; every case study loses its media at once.

100%

24h

100%

30d

GET https://cdn.atriumad.com/robots.txtexpects 200last 200 · 130ms · 3m ago

Client asset delivery

The host answers but real client media does not — usually encoding or permissions.

100%

24h

100%

30d

GET https://cdn.atriumad.com/clients/AAHA/photos/AAHA_%20APR13%20Slide%201.jpgexpects 200last 200 · 162ms · 3m ago

What it is

Not a server we run: a document root on Hostinger that we publish to over SSH. The workspace is three Node scripts and a hardened .htaccess. Every case study that renders real media pulls it from here, which makes this the single most load-bearing piece of infrastructure in the estate — the website is static and can survive most things, but not this.

The three scripts

  • scripts/build.mjs — walks public/, warns on filenames with spaces, parens or percent signs, hard-fails on .php/.cgi/.pl/.sh/.py, then wipes and re-stages dist/, dropping hidden files except .htaccess and robots.txt.
  • scripts/deploy.mjs — refuses to push if dist/.htaccess is missing, then rsync -az --delete --exclude clients/. The exclusion is the safety rail: client media on the server is never wiped by a deploy.
  • scripts/manifest.ts — read-only. Enumerates public/clients/<CODE>/{photos,reels} and prints delivery URLs; --snippet emits a paste-ready cdnAssets record for the website's overrides file.

Why filenames are a recurring failure

Client media arrives with spaces, non-breaking spaces and parentheses in the filenames. Those survive rsync but need exactly one round of percent-encoding in the URL. Encoding twice produces a 404 that looks like a missing file; not encoding at all produces a 403. The build script warns about these names precisely because the failure appears later, in the browser, far from the upload.

Server hardening

public/.htaccess removes PHP handlers, disables directory indexes, 404s every dotfile, sets X-Robots-Tag: noindex, sends HSTS, caches media immutably for a year, restricts CORS to (www.)atriumad.com, and blocks hotlinking while deliberately allowing an empty Referer so next/image server-side fetches keep working.

A 403 on a directory URL is therefore correct behaviour, not an outage — indexes are off. Only asset URLs are meaningful to monitor.

Credentials

None in the repo, by design. Auth is the atrium-cdn entry in ~/.ssh/config (HostName / User / Port / IdentityFile) with the public key registered in hPanel → SSH Access. That means deploys only work from a machine that has been set up; CI cannot publish today.

When it breaks

Symptom

A specific asset 404s but the host is up

Check

Compare the URL against `bun run manifest` output for that client code.

Fix

Almost always double-encoding, or a non-breaking space in the filename. Re-run the manifest and paste the fresh URLs into lib/case-assets.overrides.ts.

Symptom

Everything on the host is unreachable

Check

Hostinger status and the hPanel file manager for the domain.

Fix

Nothing to redeploy — the files are already there. This is a hosting incident; the website will show placeholders until it clears.

Symptom

A deploy wiped something

Check

Whether the path was under clients/ — that folder is excluded from --delete.

Fix

Anything outside clients/ is reproducible from the repo: re-run bun run deploy.

Breaks when this does

  • Atrium websiteThe public marketing site: home, services, work, pricing, about, resources, contact.
  • Chick-in-WaffleClient case study with 44 assets on the CDN; site URL not yet registered here.

Configuration

variablestatuspurpose
CDN_SSH_HOSTapps/atrium.cdn/scripts/deploy.mjs:27missingSSH alias to publish to.Defaults to atrium-cdn, which is the real alias, so the deploy works unset.
CDN_REMOTE_PATHapps/atrium.cdn/scripts/deploy.mjs:28missingRemote document root.Defaults to domains/atriumad.com/public_html/cdn.
CDN_PROTECTEDapps/atrium.cdn/scripts/deploy.mjs:29missingPath spared by rsync --delete.Defaults to clients/. Changing this can delete client media — treat it as load-bearing.

Where to start reading

  • Stage build

    apps/atrium.cdn/scripts/build.mjs
  • Deploy over SSH

    apps/atrium.cdn/scripts/deploy.mjs
  • Client asset manifest

    apps/atrium.cdn/scripts/manifest.ts
  • Server hardening

    apps/atrium.cdn/public/.htaccess

In the repo

path

apps/atrium.cdn

version

0.0.1

files

3 (0 tests)

lines

246

depends on

engineering view →

Incident history

No incidents recorded for this system.