No description
  • HTML 48.6%
  • Python 46.6%
  • TypeScript 3.4%
  • Dockerfile 1.4%
Find a file
hicham e090907449
All checks were successful
deploy / deploy (push) Successful in 52s
slides: move layout images to public/ so they ship in the build
2026-07-16 15:04:10 +02:00
.forgejo/workflows slides: slidev deck at hd.hicham.party/slides (CI-built, nginx-served) 2026-07-15 15:11:05 +02:00
conf slides: slidev deck at hd.hicham.party/slides (CI-built, nginx-served) 2026-07-15 15:11:05 +02:00
demo starter kit: ruby on macos 2026-07-15 15:01:12 +02:00
portal portal: move page to templates/index.html; align ip/port row 2026-07-15 10:37:08 +02:00
slides slides: move layout images to public/ so they ship in the build 2026-07-16 15:04:10 +02:00
.env.production expose traefik dashboard at traefik.hd.hicham.party (file provider route, basicauth via b64 env) 2026-07-15 13:29:47 +02:00
.gitignore switch to DNS-01 wildcard cert via OVH; dotenvx-encrypt secrets 2026-07-09 23:00:24 +02:00
compose.yml slides: slidev deck at hd.hicham.party/slides (CI-built, nginx-served) 2026-07-15 15:11:05 +02:00
README.md self-service portal: register routes + list published sites 2026-07-09 20:35:37 +02:00

hd.hicham.party

Workshop ingress on the reset VPS (tailnet node vps-cfccaf20, 100.64.0.2, public 51.38.236.47). Traefik in host network mode so it sits on the Tailscale mesh and can proxy straight to participant laptops.

Layout

  • compose.yml — Traefik (host net) + landing (nginx) + whoami, both on loopback.
  • conf/ — Traefik file provider (watched). One file per route.
    • landing.ymlhd.hicham.party → landing page.
    • demo.ymldemo.hd.hicham.party → whoami (proves wildcard routing; deletable).
  • landing/index.html — the landing page.
  • .envACME_EMAIL (not secret).
  • acme.json — Let's Encrypt store (git-ignored; chmod 600).

DNS (OVH)

  • hd.hicham.party A → 51.38.236.47
  • *.hd.hicham.party A → 51.38.236.47

TLS

HTTP-01 via leresolver, cert per host on first request. To switch to a single *.hd.hicham.party wildcard cert, add a DNS-01 resolver with OVH API creds.

Add a participant route

Self-service: participants go to https://hd.hicham.party (the portal app) and submit name + tailnet IP (tailscale ip -4) + port. The portal writes conf/p-<name>.yml into the shared conf volume (Traefik watches it) and lists every published site. Targets are restricted to 100.64.0.0/10; set PORTAL_TOKEN in compose.yml to require a passcode.

Manual (instructor): drop a file in conf/ (Traefik picks it up live):

# conf/alice.yml
http:
  routers:
    alice:
      rule: "Host(`alice.hd.hicham.party`)"
      entryPoints: [websecure]
      service: alice
      tls: { certResolver: leresolver }
  services:
    alice:
      loadBalancer:
        servers:
          - url: "http://100.64.0.X:PORT"   # alice's tailnet IP + port

Deploy

docker compose up -d

When pushing files from macOS via tar, suppress AppleDouble ._* sidecars — Traefik's file provider fails its whole config build on them:

COPYFILE_DISABLE=1 tar czf - compose.yml .env landing conf | ...