feat: add Caddy reverse proxy for landscaping-assistant.app (#434) #442
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ldraney/pal-e-platform!442
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "434-caddy-landscaping-assistant-app"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Changes
salt/states/caddy/Caddyfile.j2: Added two site blocks —landscaping-assistant.appwith reverse_proxy tolandscaping-assistant.tail5b443a.ts.net:443(TLS server name validated), andwww.landscaping-assistant.appwith permanent redirect to the apex domainTest Plan
curl -I https://landscaping-assistant.appreturns a valid response (once DNS is pointed)curl -I https://www.landscaping-assistant.appreturns a 301 redirect to the apex domainReview Checklist
Related Notes
ldraney/pal-e-platform #434— Configure Caddy reverse proxy for landscaping-assistant.app on edge-proxyPR #442 Review
DOMAIN REVIEW
Tech stack: Salt/Caddy (infrastructure configuration -- Jinja2 template for Caddy reverse proxy)
Architecture context: The Hetzner edge-proxy (178.156.129.142) runs Caddy as a TLS-terminating reverse proxy. Public domains hit this VPS, Caddy obtains ACME certificates automatically, and reverse-proxies upstream to Tailscale hostnames on port 443 with explicit
tls_server_namefor certificate validation. Salt manages the Caddyfile via a Jinja2 template rendered during highstate.Pattern analysis: The diff adds two hardcoded site blocks for
landscaping-assistant.app-- one reverse proxy block and one www-to-apex redirect. The pattern mirrors the original palinks.app blocks from PR #439. The Caddy configuration itself is correct:tls_server_namematching the Tailscale FQDN -- good, prevents certificate mismatchBLOCKERS
1. Stale base branch -- PR will conflict with or regress pillarized Caddyfile (BLOCKER)
PR #441 (
f7dad45) was merged to main AFTER this branch was created. That PR converted the Caddyfile.j2 from hardcoded site blocks to a data-driven Jinja2 loop overpillar['caddy']['sites']. The current main-branch Caddyfile.j2 looks like this:This PR adds hardcoded blocks below the
{%- endfor %}tag (or worse, conflicts entirely). The correct approach post-#441 is to add a pillar entry for the landscaping-assistant site, not to edit the template. The pillar entry would be:The
init.slscomment block already documents this exact pillar structure with landscaping-assistant as an example. This PR should be rebased onto current main and reworked to add pillar data instead of template hardcoding.2. Upstream hostname discrepancy (potential BLOCKER -- needs verification)
The PR uses
landscaping-assistant.tail5b443a.ts.netas the upstream target. However, the pillar example already documented ininit.slson main useslandscaping.tail5b443a.ts.net(without-assistant). One of these is wrong. The actual Tailscale machine name must be verified before merge to avoid a broken upstream.NITS
The PR body says "Follows the identical pattern established by palinks.app in PR #439" -- this is true of the original pattern, but that pattern was superseded by #441's pillarization. The PR body should reference the current approach.
No test plan entry for validating the Jinja2 template renders correctly (e.g.,
salt-call state.show_sls caddyorcaddy validate). Post-pillarization, the test plan should include verifying the rendered output includes both sites.SOP COMPLIANCE
PROCESS OBSERVATIONS
landscaping-assistant.appinstead of editing the template. Verify the correct Tailscale hostname. Open a new PR.VERDICT: NOT APPROVED
The PR is based on a stale branch and adds hardcoded site blocks to a template that has since been pillarized (PR #441). Merging would regress or conflict with the current data-driven architecture. The fix is straightforward: rebase onto main and add a pillar entry instead of editing the template. The upstream hostname (
landscaping-assistantvslandscaping) must also be verified against the actual Tailscale machine name.aabf464a6726165bfe1fRebased and reworked per QA review. The original commit added static site blocks to
Caddyfile.j2, but PR #441 has since merged and pillarized the template. The branch has been rebased onto current main and the approach changed to pillar-only:Changes in updated commit:
salt/pillar/caddy.sls(new) -- pillar data with bothpalinks.appandlandscaping-assistant.appsite definitionssalt/pillar/top.sls-- assigns caddy pillar toedge-proxyminionsalt/states/top.sls-- assigns caddy state toedge-proxyminionCaddyfile.j2-- no longer touched (template loop from #441 handles it)Tailscale hostname: Uses
landscaping.tail5b443a.ts.netper the documented expected pillar structure ininit.sls(line 22), notlandscaping-assistant.tail5b443a.ts.net.PR #442 Review (Re-review after rebase onto pillarized template)
DOMAIN REVIEW
Tech stack: Salt (pillar YAML, state top.sls). Reviewed against Salt/IaC domain checklist.
Pillar structure alignment: The new
salt/pillar/caddy.slsdefines two sites undercaddy.siteswith keysdomain,proxy_target, andwww_redirect. This matches exactly what the Caddyfile.j2 template consumes:Each expected key (
site.domain,site.proxy_target,site.get('www_redirect', false)) is present in both pillar entries. No missing keys, no extra unused keys.Proxy target verification:
landscaping.tail5b443a.ts.netmatches the hostname documented insalt/states/caddy/init.slsheader comment.palinks.tail5b443a.ts.netmatches the existing working configuration.Top.sls wiring: Both
salt/pillar/top.slsandsalt/states/top.slsadd theedge-proxyminion ID targeting thecaddypillar and state respectively. This is the correct two-file pattern -- the state needs pillar data to render, and the state must be assigned to run.Graceful reload: The init.sls (from PR #441) uses
caddy reload --config /etc/caddy/Caddyfileviacmd.runwithonchanges, so adding the landscaping site will trigger a graceful reload, not a service restart. Existing palinks.app connections are preserved.Pillar comments: The header block in
caddy.slsclearly documents all keys and their purpose. Good operator UX.Approach correctness (post-rebase): This is now purely a pillar-data change -- the template and state logic were established in PR #441. Adding a new domain is exactly the workflow the pillarization was designed to enable: add data, not logic. Clean separation.
BLOCKERS
None.
NITS
Stale PR body: The "Changes" section references
salt/states/caddy/Caddyfile.j2edits ("Added two site blocks"), but the actual diff only touchessalt/pillar/caddy.sls,salt/pillar/top.sls, andsalt/states/top.sls. This is leftover from the pre-rebase approach. The summary should be updated to reflect the pillar-only change.Extra space in comment alignment: Line 9 of
caddy.slshaswww_redirect: whether(two spaces before "whether") while other key descriptions use single space. Cosmetic only.SOP COMPLIANCE
434-caddy-landscaping-assistant-app)PROCESS OBSERVATIONS
top.slsentries will take effect once the minion is registered and a highstate is run.VERDICT: APPROVED
PR #442 Review
DOMAIN REVIEW
Stack: Salt (pillar/state management), Caddy (reverse proxy), Jinja2 templating
This PR completes the pillarization of Caddy site configuration by creating
salt/pillar/caddy.slsand wiring it into bothpillar/top.slsandstates/top.slsfor theedge-proxyminion. The change is data-only -- no template or state logic is modified.Salt compliance:
salt/states/caddy/init.slsdocuments and whatCaddyfile.j2consumes viasalt['pillar.get']('caddy:sites', {})-- keysdomain,proxy_target,www_redirectare all present and correctly typededge-proxy, which is the correct Hetzner VPS minion for Caddypalinksandlandscapingsites, so existing palinks.app routing is preserved (not a regression)init.slsis correct: file.managed -> service.running -> cmd.run with onchangesCaddy/TLS verification:
proxy_target: landscaping.tail5b443a.ts.netuses the Tailscale MagicDNS hostname. The template appends:443and setstls_server_namefor upstream certificate validation -- this prevents MITM on the Tailscale linkwww_redirect: truegenerates awww.landscaping-assistant.appblock with a permanent 301 redirect to the apex domainSecrets handling:
BLOCKERS
None.
NITS
PR body describes the wrong file. The
## Changessection says: "salt/states/caddy/Caddyfile.j2: Added two site blocks". The actual diff modifiessalt/pillar/caddy.sls(new),salt/pillar/top.sls, andsalt/states/top.sls. The Caddyfile.j2 template is untouched. The PR body should accurately describe what changed -- the pillar data and top file wiring, not the template.Pillar file comment says
www_redirectbut key iswww_redirect. Minor: the comment block at the top ofcaddy.slsuses the labelwww_redirect:with a trailing colon which reads slightly like YAML rather than documentation prose. Not a functional issue.Review checklist item "Passed automated review-fix loop" is unchecked. This is expected if this is the first review pass.
SOP COMPLIANCE
434-caddy-landscaping-assistant-appis clear)## Changessection is inaccurate -- describes Caddyfile.j2 modification but the actual diff is pillar/top file changes only (nit, not blocking)PROCESS OBSERVATIONS
curlvalidation depends on DNS being pointed first. Post-merge validation should confirm Caddy reload succeeds even before DNS cutover.VERDICT: APPROVED