Rafif Dzaky
Open to DevOps roles

Files · ~/notes/decisions

Architecture decision records

Why this site is built the way it is

Every choice here gave something up. These records say what I chose, what I rejected, and what it costs me, so the next person (or me in a year) doesn't have to guess.

Docs · ADR-001

ADR-001Accepted2026-09

Host the portfolio on my homelab, not a hosting platform

Context
A static site could live on a free hosting platform in five minutes. But the site is also evidence: I want it to run on infrastructure I operate myself.
Decision
Serve the static build from my homelab, behind Cloudflare, deployed by my own pipeline.

+ Gains

  • Real operations practice: deploys, TLS, headers, monitoring.
  • Near-zero marginal cost on a host that is on anyway.

− Costs

  • I own the uptime. A power or internet cut at home takes the site down.
  • More moving parts than a hosting platform.

Considered instead

  • Free static hosting (simplest, and the fallback if the lab is ever down for long).
  • A small VPS (about US$5 a month).

Docs · ADR-002

ADR-002Accepted2026-09

Expose the site through Cloudflare Tunnel, not port forwarding

Context
The site needs to be public; the home network must not be.
Decision
cloudflared dials out to Cloudflare. No inbound ports are opened on the router, and the origin has no public IP.

+ Gains

  • Nothing at home to scan or attack directly.
  • TLS, caching and DDoS protection at the edge.

− Costs

  • A dependency on Cloudflare for every request.
  • The hop from cloudflared to Caddy is plain HTTP, acceptable only because it stays on localhost.

Considered instead

  • Port forwarding with a dynamic-DNS name (rejected: exposes the home IP).
  • A VPS as a reverse proxy over a VPN.

Docs · ADR-003

ADR-003Accepted2026-09

Deploy with rsync over Tailscale into immutable release folders

Context
GitHub Actions has to reach a machine that has no public IP.
Decision
The runner joins my tailnet as an ephemeral, tagged node, rsyncs the build into a new release folder, and switches a `current` symlink atomically.

+ Gains

  • Rollback is one symlink switch.
  • Visitors never see a half-copied release.
  • No self-hosted runner to patch.

− Costs

  • An ephemeral node joins the tailnet on every deploy, so the ACL has to be tight.
  • Old releases need pruning.

Considered instead

  • A self-hosted runner in the lab (more to maintain, and it runs untrusted CI code at home).
  • Pull-based deploys from the host.

Docs · ADR-004

ADR-004Accepted2026-09

A static site with no backend

Context
Recruiters need to read a page, not log in or submit forms.
Decision
Astro builds plain HTML. Interactivity is client-side; contact goes through email.

+ Gains

  • Almost no attack surface: no server code, database or cookies.
  • Fast, cacheable, and cheap to run.

− Costs

  • No contact form or analytics without adding a service.
  • Live data (such as the status page) has to come from somewhere else.

Considered instead

  • A small backend for a contact form (rejected: attack surface for little value).

Docs · ADR-005

ADR-005Accepted2026-09

A CSP generated at build time with script hashes

Context
The framework's built-in CSP blocked the site's inline styles (see PM-002).
Decision
A post-build script hashes every inline script into a CSP meta tag on every page. Styles allow inline; headers that a meta tag can't set live in Caddy.

+ Gains

  • Injected scripts, inline handlers and eval are blocked.
  • The policy always matches the exact build that ships.

− Costs

  • A meta CSP can't set frame-ancestors, so that needs a server header.
  • Inline styles are allowed.

Considered instead

  • Nonces (need a server per request, which a static site does not have).
  • No CSP (rejected).

Docs · ADR-006

ADR-006Accepted2026-09

Monitor the site from outside the homelab

Context
A monitor that runs on the same host as the site cannot report that host being down.
Decision
A GitHub Action checks the public site from outside and publishes the results to the status page.

+ Gains

  • An independent vantage point, and free for a public repository.
  • Nothing in the lab has to be exposed.

− Costs

  • GitHub can delay scheduled runs, so the resolution is coarse.
  • Checks run from GitHub's network, not from Indonesia.

Considered instead

  • Uptime Kuma in the lab (useful for internal checks, blind to its own outage).
  • A paid external monitor.

recruiter@rafifdzaky: ~

Exec summary · 60 seconds

Rafif Dzaky Daniswara, DevOps Engineer

I own everything after the merge for PT PSM's 20+ production services: the pipelines that ship them, the servers they run on, and the monitoring that tells me when something drifts.

What I own today

  • CI/CD and release approvals
  • Linode VPS fleet: setup, scaling, hardening
  • Domains, DNS and SSL
  • Access, IAM and secrets
  • Monitoring and incident response

Not yet (learning in my homelab)

  • Kubernetes in production
  • AWS or GCP at scale

Evidence

Email [email protected]Contact detailsRésumé