What I use
The stack behind lans.cloud and this blog — self-hosted on one VPS.
Infrastructure
Everything runs on a single VPS, self-hosted, no managed services.
- Traefik
- Reverse proxy and automatic Let’s Encrypt TLS for every subdomain. Services publish no ports of their own — they join a shared Docker network and Traefik routes to them.
- Docker Compose
- One compose project per app. Pinned image tags, healthchecks, named volumes so data survives restarts.
- PostgreSQL 16
- The shared relational database, reachable internally as infrastructure-postgres.
- Redis 7
- Cache, sessions, queues and pub/sub, with AOF + RDB persistence.
- MinIO
- S3-compatible object storage — blog post images and project assets live here.
This blog
Astro in SSR mode, rendering markdown straight off disk.
- Astro 7
- Server-rendered via the Node adapter. Nothing is prerendered: posts are markdown folders on a mounted volume, so publishing is a file move and the change is live on the next request.
- markdown-it + Shiki
- Markdown rendering with server-side syntax highlighting — dual light/dark themes, zero client-side highlighting JavaScript.
- sanitize-html
- Defence in depth on rendered output; raw HTML in markdown is escaped rather than trusted.
- SQLite (better-sqlite3)
- Subscribers, newsletter list and magic-link tokens. Small, file-backed, trivially backed up.
- Satori + resvg
- Per-post Open Graph cards generated on demand at /og/<slug>.
Services
Self-hosted replacements for the usual third-party SaaS.
- Umami
- Privacy-friendly analytics instead of Google Analytics — no cookie banner needed.
- Remark42
- Comments, self-hosted, anonymous-friendly.
- Stripe
- The one deliberate exception to self-hosting: subscriptions and billing, with the customer portal for cancellations.
- Internal mail service
- A small internal gateway for transactional email (magic links, newsletter).
Workflow
- Neovim / VS Code
- Editing.
- Claude Code
- Pair programming, refactors, and most of the writing scaffolding for this blog.
- git + GitHub
- Private repos for infrastructure and content, public where it makes sense.
- cron
- Nightly encrypted backups pushed offsite, IndexNow pings, newsletter sends, and a watchdog for stuck payment webhooks.