From 7a29f83af2d23f6f3399e19f3879c667287252ed Mon Sep 17 00:00:00 2001 From: bndw Date: Sun, 15 Feb 2026 17:17:18 -0800 Subject: random design files --- GIT_AND_GOMOD_PLAN.md | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 GIT_AND_GOMOD_PLAN.md (limited to 'GIT_AND_GOMOD_PLAN.md') diff --git a/GIT_AND_GOMOD_PLAN.md b/GIT_AND_GOMOD_PLAN.md new file mode 100644 index 0000000..183154f --- /dev/null +++ b/GIT_AND_GOMOD_PLAN.md @@ -0,0 +1,230 @@ +# Go Vanity Import + Git Server Architecture + +This document describes a **simple, robust architecture** for hosting Go module source code and enabling `go get` on a **custom domain**, using: + +* A basic Git server (authoritative source) +* Go vanity imports +* Caddy for HTTPS with automatic TLS + +The design prioritizes: + +* Simplicity +* Long-term correctness +* Zero client-side configuration +* Easy future migration to a module proxy if needed + +--- + +## Goals + +* Host all authored Go modules under a single domain (e.g. `yourdomain.com/foo`) +* Allow anyone to run: + + ```bash + go get yourdomain.com/foo + ``` + + with no environment variables or flags +* Retain full control of source code and hosting +* Avoid unnecessary complexity (S3 proxies, CI artifact pipelines) for a single author + +--- + +## High-Level Architecture + +``` +yourdomain.com + ├─ / → Vanity import discovery (?go-get=1) + ├─ /.git → Git repository (HTTPS, read-only) + └─ ssh://git@yourdomain.com/.git → Git writes (SSH) +``` + +Components: + +* **Caddy**: Fronts everything, provides HTTPS automatically +* **Vanity Import Server**: Tiny Go HTTP server that serves `` tags +* **Git Server**: Bare Git repositories served over HTTPS and SSH + +--- + +## How `go get` Works in This Setup + +When a user runs: + +```bash +go get yourdomain.com/foo +``` + +Go performs the following steps: + +1. **Vanity discovery** + + ``` + GET https://yourdomain.com/foo?go-get=1 + ``` + +2. **Vanity server responds** with: + + ```html + + ``` + +3. **Go clones the repository**: + + ``` + git clone https://yourdomain.com/foo.git + ``` + +4. **Go reads `go.mod`**, checks tags (e.g. `v1.2.3`), and builds the module + +No Go module proxy is involved. + +--- + +## Module Requirements + +Each module repository **must**: + +* Be located at `/srv/git/.git` +* Have a `go.mod` file with: + + ```go + module yourdomain.com/ + ``` +* Use semantic version tags: + + ``` + v1.0.0 + v1.2.3 + ``` + +Tags must not be rewritten after publication. + +--- + +## Vanity Import Server + +A single Go HTTP server can serve vanity imports for **all modules**. + +### Responsibilities + +* Respond only to `?go-get=1` requests +* Dynamically map paths to Git repositories +* Serve static HTML with `` + +### Behavior + +For a request to: + +``` +/foo?go-get=1 +``` + +The server returns: + +```html + +``` + +All non-`go-get` requests return `404` (or are handled elsewhere). + +--- + +## Git Server + +### Repository Layout + +``` +/srv/git/ + ├─ foo.git + ├─ bar.git + └─ baz.git +``` + +Repositories are: + +* **Bare** +* Read-only over HTTPS +* Writable only via SSH + +### Write Access + +* SSH only +* Single `git` user +* Access controlled via `authorized_keys` + +Example push: + +```bash +git push git@yourdomain.com:/srv/git/foo.git +``` + +--- + +## Caddy Configuration + +Caddy is used as the front-facing server. + +### Responsibilities + +* Automatic HTTPS (Let’s Encrypt) +* Route `.git` paths to `git-http-backend` +* Route all other paths to the vanity import server + +### Conceptual Routing + +* `/*.git*` → Git HTTP backend +* `/*` → Vanity import server + +This keeps TLS, routing, and process management simple and centralized. + +--- + +## Why This Design Is “Bullet-Proof Simple” + +### Advantages + +* No module proxy implementation required +* No S3, CloudFront, or artifact format rules +* No CI publishing pipeline needed +* Fully compatible with Go tooling +* Easy to debug (if `git clone` works, `go get` works) +* Mirrors Go’s original and still-supported design + +### Trade-offs + +* Git-based fetching is slower than a proxy +* No immutable release guarantees beyond Git tags +* Less suitable for very high traffic + +For a single-author, self-hosted setup, these trade-offs are acceptable. + +--- + +## Future Migration Path (Optional) + +If needed later, this setup can evolve into a module proxy: + +* Keep vanity import paths unchanged +* Switch `` from `git` → `mod` +* Introduce an S3-backed module proxy +* Users do not need to change imports or commands + +This design does not lock you into Git forever. + +--- + +## Summary + +This architecture provides: + +* A single, authoritative domain for all Go modules +* Simple Git-based source hosting +* Zero-config `go get` for users +* Minimal operational complexity +* A clean upgrade path to a full module proxy + +It is the simplest solution that is still fully correct and future-proof for Go modules. + -- cgit v1.2.3