orchard
mirrorEvery site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.
blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics
1.PHONY: run build frontend clean
2
3# Vite watches and rebuilds build/dist while Go serves it from disk. Templates
4# are embedded, so a template change needs a Go restart; CSS and JS changes only
5# need a browser reload.
6#
7# Go waits for the manifest rather than sleeping a guessed number of seconds.
8# The server treats a missing manifest as fatal, so the startup order matters
9# and a cold build takes longer than any number worth hardcoding.
10#
11# SESSION_DOMAIN is left unset here so the cookie is host-only and development
12# on localhost works. Setting it to .bythewood.me locally means a login that
13# reports success and then does not stick.
14run:
15 cd frontend && bun run dev & \
16 i=0; while [ ! -f build/dist/.vite/manifest.json ]; do \
17 i=$$((i+1)); \
18 if [ $$i -gt 120 ]; then echo "vite did not produce a manifest in 60s" >&2; exit 1; fi; \
19 sleep 0.5; \
20 done; \
21 go run .
22
23frontend:
24 cd frontend && bun install --frozen-lockfile && bun run build
25
26# The release binary. -tags embed swaps assets_disk.go for assets_embed.go, so
27# the Vite bundle is compiled into the executable. The prerequisite is a
28# requirement rather than ordering: the embed directive reads build/ at compile
29# time and fails if it is not there.
30build: frontend
31 go build -tags embed -trimpath -ldflags="-s -w" -o ../../bin/auth.bythewood.me .
32
33clean:
34 rm -rf build frontend/node_modules