Commit Graph
16 Commits
Author SHA1 Message Date
valknar b0dba5bf40 fix(traefik): explicitly define the traefik entrypoint on :8080
--api.dashboard=true alone wasn't enough - the API returned 404 on
every path after enabling it. Traefik apparently doesn't reliably
auto-create the default "traefik" entrypoint the way older docs
describe; defining it explicitly is the documented, reliable way to
get the API/dashboard router actually listening. Still not in ports:,
so still only reachable from other containers on falcon_network.
2026-08-17 18:48:41 +02:00
valknar f207009efd add system and traefik widgets to pulsenode; enable Traefik API
- traefik/compose.yml: flip --api.dashboard=true so Traefik's internal
  API is reachable. No entrypoint named "traefik" is defined, so
  Traefik auto-creates its default one on :8080 - not published to the
  host (only 80/443 are), so it's reachable only from other containers
  on falcon_network, i.e. exactly (and only) pulsenode.
- pulsenode/config.yml: adds a system widget and swaps the plain
  Traefik docker card for the real traefik widget (router/entrypoint/
  middleware view via that now-enabled API), both at the top of
  Services.

Verified locally before deploying: a plain container (no pid: host,
no /proc,/sys mounts) already reports host-accurate CPU count, memory
total, and root disk usage via systeminformation, since Docker doesn't
namespace /proc/stat, /proc/meminfo, or overlayfs df by default. No
privilege escalation needed for the system widget after all - tested
side by side against the real host's nproc/free/df output. Also
confirmed the merged config.yml validates against the app's own zod
schema, not just as YAML.
2026-08-17 18:46:51 +02:00
valknar 318f48036d refactor: move vpn-only middleware from falcon.yaml to security.yaml
falcon-vpn-only was defined inline in falcon.yaml even though it's a
generic ipAllowList restriction with nothing falcon-specific about it
- security.yaml is where the other reusable middlewares (security-
headers, no-index, rate-limit) already live. Renamed to vpn-only to
match their bare naming style now that it's not tied to one file, and
updated falcon.yaml's two router references to vpn-only@file (same
cross-file pattern already used there for security-headers@file).

Also applies it to the pulsenode stack: it's a dashboard surfacing
container names/health for every service here, and there's no auth in
front of it yet, so gating it to the tailnet is a real mitigation for
that gap rather than leaving it open on the public hostname.
2026-08-17 15:54:40 +02:00
valknar 6e96e33875 feat(traefik,headscale): restrict falcon.pivoine.art to Tailscale mesh only
Add a Traefik IP allowlist so *.falcon.pivoine.art rejects any source
outside the Tailscale/Headscale CIDR ranges, even though DNS still
resolves publicly. Pair it with a headscale MagicDNS override so
tailnet clients resolve the hostname straight to the VPS's tailscale
IP and route correctly.

Requires Docker's userland-proxy disabled on the VPS host
(/etc/docker/daemon.json) so Traefik sees real client source IPs
instead of the docker bridge gateway — done manually, not tracked
in this repo.
2026-08-16 16:51:53 +02:00
valknar 184200299d feat(traefik): route *.falcon.pivoine.art to apps on falcon over Tailscale
Falcon (home machine) stays off the public internet; the VPS Traefik
terminates TLS/ACME as usual and forwards to falcon's tailnet IP.
2026-08-16 16:32:21 +02:00
valknarandClaude Sonnet 4.6 8d33836714 fix(gitea): block scraper IP and add rate limiting
74.7.243.196 was crawling valknar/home SVG icon tree at 1.8 req/s.
- Denylist the IP in fail2ban dynamic config
- Add rate-limit@file middleware to Gitea's Traefik router to throttle
  future scrapers on public repos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 10:27:56 +02:00
valknarandClaude Sonnet 4.6 3265d69a6c fix(traefik): upgrade fail2ban plugin to v0.9.0 and fix config schema
v0.7.1 caused 403 on all routes. v0.9.0 renamed whitelist→allowlist,
changed ip to a comma-separated string, and added enabled/statuscode fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 10:09:37 +02:00
valknarandClaude Sonnet 4.6 586f137cf9 feat(traefik): add fail2ban plugin with global middleware
Registers tomMoulard/fail2ban v0.7.1 as an experimental plugin and
applies it globally on the web-secure entrypoint alongside security-headers.
Bans IPs after 5 failures within 10 minutes for 3 hours; whitelists
RFC1918 ranges to protect internal/Docker traffic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 10:05:11 +02:00
valknarandClaude Sonnet 4.6 28b31e91e4 chore: add .env.example files for all stacks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 18:55:30 +02:00
valknar 990ab0730a fix: no-index 2026-04-10 19:47:10 +02:00
valknar adfb6032ee chore: format 2026-03-18 17:39:36 +01:00
valknar 74768a3ce5 chore: traefik without watchtower 2026-03-06 10:29:48 +01:00
valknar 1865844260 chore: cleanup 2026-03-05 09:51:40 +01:00
valknar d0c38c1f46 fix: traefik image tag 2026-03-02 09:49:14 +01:00
valknarandClaude Opus 4.6 e7bad9cbcb Add coolify network to traefik for Coolify container routing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 23:03:17 +01:00
valknarandClaude Opus 4.6 f21e0611b4 Add self-contained Docker Compose stacks for pivoine.art infrastructure
Migrated 11 services from monolithic docker-compose project into independent stacks,
each with dedicated databases, minimal .env configuration, and bind-mount data volumes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:41:50 +01:00