Literally this git forge
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-17 14:53:05 -04:00
cloud-init Fix ssh server and git user permissions 2026-09-17 14:53:05 -04:00
.gitignore Initial Commit 2026-09-17 14:39:48 -04:00
main.tf Initial Commit 2026-09-17 14:39:48 -04:00
outputs.tf Initial Commit 2026-09-17 14:39:48 -04:00
providers.tf Initial Commit 2026-09-17 14:39:48 -04:00
README.md Initial Commit 2026-09-17 14:39:48 -04:00
terraform.tfvars Initial Commit 2026-09-17 14:39:48 -04:00
variables.tf Initial Commit 2026-09-17 14:39:48 -04:00
versions.tf Initial Commit 2026-09-17 14:39:48 -04:00

forge

Terraform config for a small Hetzner Cloud (hcloud) server hosting:

  • Forgejo — git hosting (web UI + git-over-SSH on port 22, the main intended function of this box)
  • Soft Serve — SSH-based git repo browser/TUI, separate SSH port
  • Caddy — automatic HTTPS (Let's Encrypt) reverse-proxying to Forgejo
  • A public, passwordless console SSH user intended as a restricted-shell TUI frontend (stubbed for now — real program TBD, likely Guile Scheme, to live in its own repo later)

Port layout

Forgejo and the system's own sshd both want port 22 by default. Since Forgejo hosting git is this box's main job, Forgejo keeps port 22 and the system sshd is moved instead:

Port Service
22 Forgejo (web UI on 443 via Caddy, git-over-SSH on 22)
443 Caddy (HTTPS)
2222 System sshd — your admin login, and the public console user
23231 Soft Serve SSH

ssh -p 2222 console@git.keane.sh requires no key/password at all (AuthenticationMethods none in sshd config) and is forced into /usr/local/bin/console-shell regardless of what command is requested — currently a stub, replace with the real program later.

Setup

export TF_VAR_hcloud_token=<your Hetzner Cloud API token>

terraform init
terraform plan
terraform apply

terraform.tfvars already contains real values (SSH public keys, admin email) — it's committed, not gitignored, since public keys are meant to be public and none of that file's contents are sensitive. Edit it directly if you need to add/change keys. The only actual secret (the Hetzner API token) never goes in a file — it's passed via the TF_VAR_hcloud_token environment variable instead.

Assumes a Route53 hosted zone for keane.sh already exists in the AWS account your default credentials point at (same account/credentials used elsewhere — not a new one).

Backups

Hetzner's automatic daily-snapshot backups feature is enabled (backups = true on the server resource, ~20% surcharge on the server price) — no separate backup scripting needed.

Notes / TODO

  • Forgejo version is pinned in cloud-init/user-data.yaml.tftpl — bump the URL there when you want to upgrade.
  • SQLite is used for Forgejo's DB (single-user instance, no need for Postgres).
  • The console shell is currently a stub (/usr/local/bin/console-shell) — once the real Guile TUI program exists in its own repo, update the cloud-init runcmd to fetch/build it instead, or manage it out-of-band via SSH once the box is up.
  • Soft Serve currently hosts an independent set of repos from Forgejo (no automatic sync between the two) unless you decide to wire that up later.