F06Lab 01 · November 2026
How this site runs
m-ashraf.com is hand-written HTML and CSS, with no framework and no database, served from a Linux server I run myself. The same server hosts my other projects, each one walled off from the rest.
- Server
- Oracle Cloud ARM64 VM · 4 cores · 24 GB RAM · Ubuntu 24.04 LTS
- Front door
- Caddy: automatic HTTPS certificates and routing for every app
- Isolation
- One Linux user, folder and set of systemd services per app
- Backups
- Nightly snapshots of every app's data, kept for 14 days
The path of a request
- DNSm-ashraf.com points at the server. A wildcard record sends every subdomain there too, so a new app never needs a DNS change.
- FirewallOnly SSH, HTTP and HTTPS are reachable from outside; everything else is rejected. SSH accepts keys only, with password login switched off.
- One door inCaddy is the only program listening on the internet. It gets and renews HTTPS certificates by itself, redirects HTTP to HTTPS, and routes each address to the right app.
- The appFor this site, Caddy serves the files directly. Every other app listens on a private port that can't be reached from outside, and Caddy forwards to it.
Every app in its own box
The rule on this server: everything an app needs lives in its own folder, and adding, changing or removing one app never touches another.
- Its own Linux user, so one compromised app can't read another's files or keys.
- Code it can only read, and one data folder it's allowed to write to.
- Its own Python environment and secrets file, readable by that app alone.
- Its own systemd services, restarted automatically if they crash.
- Its own small Caddy config. The main config only imports them, so it never needs editing.
Security updates install automatically, and a nightly job snapshots every app's data and keeps 14 days of them.
This site
- Plain HTML, CSS and a little JavaScript. No trackers and no third-party requests: even the fonts are served from here.
- Strict security headers: a Content-Security-Policy that only allows this site's own files, HSTS, and no framing by other sites.
- Light and dark themes, readable on a phone, and it still works with JavaScript turned off.
Deploying is one command
From my PC, sh deploy/deploy.sh runs four steps:
- CheckEvery internal link and image must resolve, and nothing that looks like a key, a token or a phone number is allowed to ship.
- UploadThe site goes to the server as one archive over SSH.
- SwapThe new version replaces the old one in a single move, so visitors never see half an update.
- VerifyThe script fetches the live page and confirms it answers.
What I'd add next
- Uptime monitoring that alerts me when something stops answering.
- IPv6.
- Privacy-friendly visitor numbers from Caddy's own logs, without cookies or trackers.