A Privacy Friendly Portfolio

Updated: 4 weeks, 1 day ago

Most "privacy-focused" websites stop at removing Google Analytics. That's a start, but tracking happens at every layer of the stack; the domain registrar, the hosting provider, the reverse proxy and the framework. Building something that genuinely minimises data collection means making deliberate choices at each of those layers.

My portfolio, erikwalther.eu, is also a practical experiment in how far you can take that on a single VPS. Here's what the stack looks like and why each piece was chosen.

Domain: Njalla

I registered erikwalther.eu with Njalla. Rather than acting as a traditional registrar, Njalla purchases the domain on your behalf and holds it in their name so your personal details never appear in the WHOIS record.

The practical benefit is straightforward: no name or address exposed to scrapers, spammers, or data brokers via WHOIS lookups. Njalla is based in Nevis, which does add some distance from European legal processes for the domain record specifically. Though it's worth being clear that this isn't an impenetrable legal shield, just a layer of separation that most registrars don't offer.

Hosting: Hetzner (Falkenstein, Germany)

The application runs on a Hetzner Online GmbH VPS in Falkenstein, Germany. The main reason is jurisdiction: all data is processed and stored within the EU, which avoids exposure to US-based surveillance laws like the CLOUD Act. American providers, including their EU subsidiaries, can be compelled to hand over data under that legislation without notifying the user. Hetzner, as a German company operating German infrastructure, isn't subject to it.

Hetzner also doesn't scan traffic for ad targeting or use server data for other commercial purposes. You get compute, nothing more.

One thing worth being precise about: "zero knowledge" of visitors applies at the application layer. Hetzner, as the network provider, has visibility at the infrastructure level. That's true of any hosted setup and is stated clearly in the privacy policy.

The Stack: Django, Gunicorn, and Caddy

Django

Django gives explicit control over what data is processed and when. There are no plugins phoning home, no update-check beacons, no third-party calls unless I write them. The settings.py configuration enforces a few hardened defaults worth calling out:

  • SECURE_SSL_REDIRECT = True makes sure all requests redirected to HTTPS
  • SECURE_HSTS_PRELOAD = True makes sure once a browser visits, it won't attempt plain HTTP again, eliminating the window for downgrade attacks on subsequent visits
  • Cookies flagged HttpOnly and Secure

The only cookie set by this site is Django's csrftoken. This is a technically necessary token that prevents Cross-Site Request Forgery attacks. It contains no personal data and expires after one year. There are no analytics cookies, no session tracking, no advertising pixels. Open your browser's developer tools and that's all you'll find.

Gunicorn & Caddy

Gunicorn serves the Django application with max_requests and max_requests_jitter configured to recycle workers periodically, preventing memory accumulation over long uptimes.

Caddy sits in front as the reverse proxy, handling automatic TLS via ACME, HTTP/2 and HTTP/3, zstd/gzip compression, and static file serving with immutable cache headers. Access logs are configured to rotate and delete automatically after 30 days, matching exactly what the privacy policy commits to.

Security Headers

Both the Caddyfile and settings.py work together to send the following on every response:

Header Value Purpose
X-Content-Type-Options nosniff Prevents MIME-sniffing attacks
X-Frame-Options DENY Prevents clickjacking
Referrer-Policy same-origin Stops the referrer header leaking to external sites
Permissions-Policy (restrictive) Disables geolocation, microphone, and camera access
Content-Security-Policy (strict allowlist) Blocks resources not explicitly permitted

The Privacy Policy

The privacy policy is written to reflect the actual technical reality of the site rather than boilerplate. Effective May 16, 2026, the key points:

  • No analytics. No Google Analytics, Matomo, Plausible, or any other tool. Traffic volumes and visitor origins are genuinely unknown to me.
  • Minimal logging. The server logs IP addresses, User-Agents, request paths, referrers, and timestamps. This is standard for any web server and unavoidable for security purposes. Logs are deleted after 30 days.
  • Legal basis. Processing is grounded in GDPR Article 6(1)(f) legitimate interests for security logging and Article 6(1)(b) for the CSRF cookie. Not a catch-all consent checkbox.
  • User rights. The policy enumerates GDPR rights clearly: access, erasure, and objection. Requests go to erik@erikwalther.eu.

Tor Onion Service

For users who need stronger anonymity guarantees, the site is available as a v3 Tor Hidden Service:

hcb724zual6bxrg2jncfask2kwxlq3pnnjd2s2iq2vspwedz5b7sjqid.onion

The clearnet site includes an Onion-Location HTTP header, which causes Tor Browser to automatically prompt users to switch without requiring any manual copy-pasting.

The security model here is meaningfully different from standard Tor browsing. Because traffic never exits the Tor network to reach a clearnet exit node, it's not subject to exit node eavesdropping. Neither your ISP nor Hetzner can see the content of your communication or identify your IP address. This makes the onion service a practical option for journalists, researchers, or anyone operating in a higher-risk context, not just a novelty.

Responsible Disclosure

Since the site openly publishes its stack, it invites scrutiny. The privacy policy doubles as a security policy with concrete commitments:

  • No legal action against researchers following responsible disclosure guidelines
  • Reports acknowledged within 48 hours
  • 30-day remediation target before coordinated public disclosure
  • PGP-encrypted reports accepted (public key at /.well-known/security.txt)

What This Actually Achieves

The result is a site with a minimal data footprint: one technically necessary cookie, 30-day log retention, no third-party requests, EU-only data residency, and an onion address for users who want it.

It's not a perfect privacy solution. Hetzner has infrastructure-level visibility, Tor has its own threat model, and any server that receives requests necessarily logs something. But the choices here are deliberate, documented, and consistent with what the privacy policy actually says. That alignment between technical implementation and stated policy is, in practice, rarer than it should be.