Self-hosting
Running a gateway of your own, from a clone. This is the development setup;
for a real host, the operator's runbook in deploy/RUNBOOK.md covers
provisioning, backups, replication and delivery.
What you need
- Go 1.27 or later
- Docker with Compose
git2.29 or later,ssh, andssh-keygen
Start PostgreSQL and the object store
cp .env.example .env
make up
make up waits until both containers are healthy. The binaries read .env
from the directory you run them in, so run them from the checkout root — or
point OTISK_ENV_FILE at the file. Anything already set in the environment
takes precedence, which is how the compose stack configures them.
PostgreSQL holds metadata only — accounts, keys, repository records, the ref mirror — and never git object data.
Build
make build
This produces bin/git-gateway and bin/otisk.
Create the first account
./bin/git-gateway bootstrap -handle yuritomanek -key ~/.ssh/id_ed25519.pub
This is the only command that needs access to the host, and it has to be: authenticating over SSH requires a key that is already registered. Everything after this happens over SSH.
Run the gateway
From the checkout root, so it finds .env:
./bin/git-gateway serve
It applies any pending migrations on start and listens on :2222 by default.
Use it
otisk host set git@localhost:2222
otisk whoami
From here, getting started applies as written, with
git@localhost:2222 wherever it says a host.
Development
make lint # gofmt and go vet, no tools to install
make test # the full suite, with the race detector
make verify # the same, refusing a run that skipped more than expected
make build # binaries into ./bin
make up # start PostgreSQL and the object store
make down # stop them, keeping volumes
Tests need the stack running: they create an isolated database and bucket per
test and drop them afterwards. Without it they skip rather than fail — which
is why make verify exists, and why it refuses a run where more tests skipped
than expected.
Stock git is kept available as a correctness oracle — internal/oracle
compares otisk's view of a repository against git cat-file, object by
object. That matters most for work not yet done: serving objects by parsing
packfiles directly is exactly the kind of change that can silently return
wrong bytes.
Planning artifacts live in openspec/.