Skip to content

← Blog

Three Sites One Admin One Postgres

Three sites, one Postgres, $8/month. That’s my Wagtail stack in production.

Three Sites One Admin One Postgres

Three sites, one Postgres, $8/month. That’s my Wagtail stack in production.

What I got out of the box:
1. Multi-site by hostname. One Wagtail project, the Site model routes www / tech / books to separate trees and templates. Single admin, single Postgres.
2. Per-field translations as a first-class pattern. Each model has field + field_pt; a tiny template tag picks based on the active language (cookie). UI strings use gettext/rosetta.
3. Search without extra infra. Model SearchField + DB backend → host-scoped /search/?q=... with no Elasticsearch.
4. Atom/RSS feeds. django.contrib.syndication + a host-aware dispatch → three independent feeds at /feed/ per subdomain.
5. Multi-site sitemaps. wagtail.contrib.sitemaps respects host routing automatically.
6. Revisions, drafts, scheduling, media library, image renditions — all in admin, no custom code.

What I actually wrote:
1. A display_* property pattern on book posts so they always render in the book’s native language (not the viewer cookie).
2. Two manage.py AI commands: translate EN↔PT page fields via a platform prompt, and extract real titles + 25–40 word summaries from markdown.

How I run it:
1. AWS Lightsail (eu-west-1) VM ~ $8/month: Postgres 16 + gunicorn + nginx + Certbot.
2. Media on S3 with signed URLs; Wagtail renditions serve the right size.
3. One-command deploy from laptop triggers a VM script: pull, migrate, collectstatic, compilemessages, idempotent bootstrap, restart, HTTP health-check, auto-rollback to previous SHA on non-200.
4. Observability is coherent: structured gunicorn access/error logs via journalctl; health-check gates deploys; systemd Restart=on-failure; log lines on every backup and deploy step.
5. Backups: weekly pg_dump to S3 (encrypted, lifecycle keeps last N). Restore tested.
6. Apex 301 to www, HTTPS everywhere, HSTS on all three subdomains.

You don’t need Elasticsearch for small Wagtail search. I also skipped App Runner — wrong shape for multi-site with shared admin.

What I’d add next: Plausible Analytics (already wired, off for now) and real APM/tracing only when traffic justifies it.

If you’re running Django/Wagtail in prod, what’s the smallest observability + rollback setup you actually trust before adding APM?

P.S. Live: https://www.bilouro.com/ • Code: https://github.com/bilouro/bilouro-web

P.S. New tech post every Wednesday.