collin/anvil
RenderedSource
anvil
A git forge built using gitoxide.
Architecture
A Cargo workspace. The keystone is anvil-git: gix is a client library
with no server-side protocol, so anvil supplies its own transport-agnostic
upload-pack/receive-pack (smart-HTTP and SSH share one implementation).
| Crate | Responsibility |
|---|---|
anvil-core | Domain model, SQLite persistence, on-disk bare-repo storage |
anvil-git | Server-side git wire protocol on gix (upstream-candidate) |
anvil-web | axum HTTP server: web UI + smart-HTTP git endpoints |
anvil-ssh | git-over-SSH (russh) |
anvil-cli | anvild daemon + admin CLI |
Quick start
cargo run -- migrate # create data/ + database
cargo run -- user create alice --password secret # create a user
cargo run -- repo create alice/hello # create a bare repo on disk
cargo run -- serve # start the server
Configuration is optional; see anvil.example.toml.
PORT/HOST and ANVIL_BASE_URL (or PORTLESS_URL) override the listen
address and public URL, so a proxy can place anvil without a config file.
To run it the way it runs in production — in Docker, with CI able to reach the
host's Docker socket — use ./deploy/dev.sh, which builds the image, starts a
container, and (with portless) serves
it over HTTPS at https://anvil.localhost.
Deploying
compose.yaml describes the deployment; hag, the shared deploy tool for
every project on hagrid, runs it there. The image carries a prebuilt static
binary rather than compiling in Docker, so one step comes first:
./deploy/deploy.sh # cross-compile, build, push, then restart on the host
./deploy/deploy.sh -n # dry run: print every step, change nothing
hag status # what the host is running
hag logs -f # its logs
Full details, including first-run setup and the CD webhook, are in DEPLOY.md.
Docs
- CI artifacts
- Remote runners — dial-out runners so CI executes off-box; design, not yet built
- Single sign-on — OIDC sign-in, alongside passwords
- Repository secrets — encrypted to your ssh keys in the browser; anvil stores ciphertext it cannot open
- Threat model for untrusted users