105 lines
3.5 KiB
Markdown
105 lines
3.5 KiB
Markdown
# Hetzner single-node bootstrap
|
||
|
||
This repo’s canonical infrastructure path is:
|
||
|
||
1. provision one Hetzner VM with Terraform
|
||
2. let cloud-init install k3s (and optionally Tailscale)
|
||
3. run `scripts/hetzner/bootstrap.sh` from the operator workstation
|
||
4. apply repo-managed platform + project manifests
|
||
5. bootstrap Forgejo, the runner, repo secrets/variables, and the first CI-driven deploy
|
||
|
||
## Source of truth
|
||
|
||
Use these docs first:
|
||
|
||
- `docs/hetzner-k3s-bootstrap.md` — bootstrap + destroy + required env
|
||
- `docs/hetzner-self-hosted-ci-runbook.md` — Forgejo/runner/CI flow
|
||
- `docs/k8s-observability.md` — Grafana, Loki, Promtail, Headlamp
|
||
- `deploy/k8s/README.md` — Kubernetes layout
|
||
- `deploy/k8s/overlays/hetzner-single-node/README.md` — overlay details
|
||
|
||
## Current architecture
|
||
|
||
Infrastructure under `infra/terraform/hetzner/` provisions:
|
||
- one Hetzner VM
|
||
- one firewall
|
||
- one private network attachment
|
||
- cloud-init for unattended k3s install
|
||
|
||
Kubernetes platform services deployed from this repo:
|
||
- Forgejo
|
||
- Forgejo runner
|
||
- private registry
|
||
- cert-manager
|
||
- Traefik via k3s bundled ingress controller
|
||
- Grafana
|
||
- Loki
|
||
- Promtail
|
||
- Headlamp
|
||
|
||
Project services deployed from this repo:
|
||
- Redpanda
|
||
- `near-intents-ingest`
|
||
- `dummy-reactor`
|
||
- `dummy-executor`
|
||
- `dummy-consumer`
|
||
|
||
## Bootstrap model
|
||
|
||
The current bootstrap is workstation-driven after Terraform.
|
||
cloud-init does **not** clone this repo onto the node.
|
||
|
||
`scripts/hetzner/bootstrap.sh` now:
|
||
- loads config and secrets from `scripts/hetzner/bootstrap-secrets.env`
|
||
- resolves `*_PASS` values through `pass`
|
||
- runs Terraform
|
||
- configures DNS through Cloudflare or Porkbun when credentials are present
|
||
- fetches kubeconfig from the node
|
||
- renders `.state/hetzner/generated-overlay/`
|
||
- applies platform + project manifests
|
||
- bootstraps Forgejo admin/user/repo/runner state
|
||
- seeds the repo into Forgejo
|
||
- lets Forgejo Actions perform the routine image build + deploy path by default
|
||
|
||
Legacy local-image bootstrap still exists, but the default/steady-state path is Forgejo Actions.
|
||
|
||
## Required operator inputs
|
||
|
||
Create and source:
|
||
|
||
```bash
|
||
cp scripts/hetzner/bootstrap-secrets.env.example scripts/hetzner/bootstrap-secrets.env
|
||
source scripts/hetzner/bootstrap-secrets.env
|
||
```
|
||
|
||
At minimum you need:
|
||
- Hetzner credentials
|
||
- SSH public key path
|
||
- public domain settings
|
||
- registry credentials
|
||
- app secret(s)
|
||
- Forgejo admin credentials
|
||
- Grafana admin credentials
|
||
|
||
Recommended:
|
||
- Tailscale auth key for private admin/control-plane access
|
||
- DNS provider credentials
|
||
- `pass`-backed secret refs instead of raw env values
|
||
|
||
## Current live/public surfaces
|
||
|
||
- Forgejo: `https://git.doran.133011.xyz/`
|
||
- Registry: `https://registry.doran.133011.xyz/`
|
||
- Grafana: `https://grafana.doran.133011.xyz/`
|
||
- Headlamp: `https://headlamp.doran.133011.xyz/`
|
||
|
||
## Notes
|
||
|
||
- The Forgejo runner no longer reads a pre-seeded `runner_registration_token` from a secret. Bootstrap generates a one-time token in-cluster and persists the runner config on the Forgejo PVC.
|
||
- Registry auth is created imperatively during bootstrap from `REGISTRY_USERNAME` and `REGISTRY_PASSWORD`; manual overlay applies must provide `registry.htpasswd` themselves.
|
||
- Headlamp login uses a generated Kubernetes service-account token; bootstrap stores it in `pass` when `HEADLAMP_ADMIN_TOKEN_PASS` is configured.
|
||
- Ingress is Traefik-based. The old `ingress-nginx` path is obsolete.
|
||
|
||
## Status
|
||
|
||
This path has been rebuilt successfully and the cluster is operational, but if you want the strongest reproducibility guarantee after any new platform addition, do one more full destroy/rebuild rehearsal.
|