aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md81+35 −46
1 files changed, 35 insertions, 46 deletions
diff --git a/README.md b/README.md
index 2db136f..6c3ff10 100644
--- a/README.md
+++ b/README.md
@@ -1,34 +1,35 @@
# Gilti — a tiny Git server in a box
-Gilti is a tiny web UI for Git that can function as either a read-only showcase
-or a Git SSH server by integrating with the system's `sshd`. It is designed for
-open-source projects and small teams that want to break free from major hosting
-platforms but aren't ready to host complex services like Forgejo.
+Gilti packages [cgit](https://git.zx2c4.com/cgit/),
+[Gitolite](https://gitolite.com/gitolite/), nginx, OpenSSH, and fcgiwrap into
+one OCI service with a Helm chart. It is intended for small authoritative Git
+installations where SSH is the only Git transport and selected repositories are
+published through a read-only web interface.
-> Gilti is a young project. Mirror your repositories and create backups.
+The first Gilti installation is `vcs.dimidiumlabs.io`, the authoritative Git
+service for Dimidium Labs.
+
+> Gilti is in its infancy. Back up the persistent volume and test restoration
+> before storing irreplaceable repositories.
## Security boundary
-- Git fetch is available anonymously over smart HTTP; authenticated fetch and
- push use SSH public-key authentication through `gilti-ssh`.
-- Every configured key has read/write access to every repository and may create
- a repository by pushing to its name for the first time.
-- Repository browsing, archives, LFS downloads, and smart HTTP fetches are
- anonymous and read-only; every repository is publicly visible.
-- Password authentication, shells, forwarding, and tunnels are disabled; content
- filters are not supported. Optional unauthenticated HTTP writes must be
- enabled explicitly.
+- Git fetch and push use SSH public-key authentication through Gitolite.
+- cgit is anonymous and read-only. It does not inherit Gitolite ACLs.
+- Only repositories exported to Gitolite's `gitweb` pseudo-user are listed by
+ cgit; unrestricted repository scanning is deliberately disabled.
+- Smart HTTP, password authentication, shells, forwarding, tunnels, and cgit
+ filters are disabled.
- Gilti is a single-replica service backed by one POSIX persistent volume. It is
not an HA system.
## Container
-Every start requires a static `authorized_keys` file:
+A fresh state directory requires an administrator public key:
```console
-docker pull ghcr.io/dimidiumlabs/gilti:nightly
+docker build -t gilti:dev .
ssh-keygen -q -t ed25519 -N '' -f ./admin
-cp ./admin.pub ./authorized_keys
docker run --rm \
--read-only --cap-drop ALL \
@@ -36,38 +37,31 @@ docker run --rm \
--cap-add SETGID --cap-add SETUID --cap-add SYS_CHROOT \
--tmpfs /run:rw,nosuid,nodev,noexec,size=32m \
--tmpfs /tmp:rw,nosuid,nodev,noexec,size=256m \
+ --tmpfs /var/cache/cgit:rw,nosuid,nodev,noexec,size=1g \
-p 8080:8080 -p 2222:2222 \
-v gilti-state:/var/lib/gilti \
- -v "$PWD/authorized_keys:/etc/gilti/authorized_keys:ro" \
- ghcr.io/dimidiumlabs/gilti:nightly
+ -v "$PWD/admin.pub:/run/gilti-bootstrap/admin.pub:ro" \
+ gilti:dev
```
-The HTTP configuration is read from the environment at startup:
-
-- `GILTI_ROOT_TITLE` (default: `Gilti`);
-- `GILTI_ROOT_DESCRIPTION` (default: `A tiny Git server`);
-- `GILTI_CLONE_PREFIX` (empty by default);
-- `GILTI_HTTP_WRITE` (`0` by default; `1` enables unauthenticated HTTP pushes and LFS uploads).
-
-Gilti snapshots the authorized keys file at process startup; changing it takes
-effect after a restart. Repositories and the persistent SSH host key live on
-the state volume.
+The bootstrap key is used only when the volume is fresh. Subsequent starts do
+not require it. Partial Gitolite state fails closed instead of being
+reinitialized. SSH host keys live on the same volume and remain stable across
+pod replacement.
## Helm
-Configure the allowed public keys in values:
-
-```yaml
-ssh:
- authorizedKeys:
- - ssh-ed25519 AAAA... operator@example
-```
+Create the bootstrap Secret before the first install:
```console
+kubectl create namespace gilti
+kubectl -n gilti create secret generic gilti-bootstrap \
+ --from-file=admin.pub="$HOME/.ssh/id_ed25519.pub"
+
helm upgrade --install gilti ./charts/gilti \
- --namespace gilti --create-namespace \
- --values values.yaml \
- --set web.clonePrefix='ssh://git@git.dimidiumlabs.io/'
+ --namespace gilti \
+ --set bootstrap.existingSecret=gilti-bootstrap \
+ --set cgit.clonePrefix='ssh://git@vcs.dimidiumlabs.io/'
```
See [`charts/gilti/README.md`](charts/gilti/README.md) for persistence, routing,
@@ -79,17 +73,12 @@ Provision tools and run static checks:
```console
mise bootstrap
-cargo fmt -- --check
-cargo test --locked
-cargo clippy --locked --all-targets -- -D warnings
shellcheck scripts/*.sh tests/*.sh
mise run chart -- --chart charts/gilti --lint-only
```
-The CI matrix builds architecture-specific Alpine artifacts before assembling
-the image; the Dockerfile does not compile source code. Linux packages are
-intentionally not produced. Gilti's release artifacts are a multi-platform OCI
-image and an OCI Helm chart.
+Linux packages are intentionally not produced. Gilti's release artifacts are a
+multi-platform OCI image and an OCI Helm chart.
## Contributing