docs/admin.org
154 lines · 6332 bytes
1#+title: gitbay admin guide
2
3One static binary (=gitbayd=), one SQLite file, bare repositories on
4disk, and the system =git=. Schema migrations run automatically on
5startup and on every admin command.
6
7* Install
8
9Build from source (=go build ./cmd/gitbayd=), install via the vanity
10module path (=go install gitbay.org/gitbay/cmd/gitbayd@latest=), or use
11a release build: =deploy/release.sh <tag>= cross-compiles reproducible
12linux/amd64, linux/arm64, and darwin/arm64 binaries with a SHA256SUMS
13manifest (CGO off, trimpath, stripped — byte-identical per commit and
14toolchain).
15
16#+begin_src sh
17install -m 755 gitbayd /usr/local/bin/
18adduser --system --group --home /var/lib/gitbay --shell /usr/sbin/nologin gitbay
19install -d -o gitbay -g gitbay -m 750 /var/lib/gitbay
20gitbayd --config /etc/gitbay/config.toml check-config
21#+end_src
22
23=deploy/= in the source tree has a cloud-init file, a hardened systemd
24unit, and a nightly backup timer. Run as the unprivileged =gitbay= user;
25the unit's =AmbientCapabilities=CAP_NET_BIND_SERVICE= covers ports
2622/80/443 without root.
27
28** The SSH port decision
29
30- =ssh.mode = "embedded"= (default): gitbayd itself listens, normally on
31 22 — move the host's admin sshd to another port. Remotes read
32 =git@host:owner/repo= with no port gymnastics.
33- =ssh.mode = "system"=: the host sshd owns 22 and invokes gitbayd via
34 =AuthorizedKeysCommand=:
35 #+begin_example
36 AuthorizedKeysCommand /usr/local/bin/gitbayd --config /etc/gitbay/config.toml authorized-keys %t %k
37 AuthorizedKeysCommandUser gitbay
38 #+end_example
39 sshd requires that binary to be root-owned and not group/world
40 writable. Unknown keys fail authentication inside sshd, so system mode
41 requires =registration.mode = "closed"= (check-config enforces this).
42
43* Configuration reference
44
45=/etc/gitbay/config.toml=. =check-config= validates and names every
46contradiction; =--no-host-checks= skips port/path probes.
47
48** [server]
49- =root= (default =/var/lib/gitbay=) — repositories, database, host
50 keys, ACME cache all live here.
51- =site_url= (required) — canonical =https://host=; drives ACME, clone
52 URLs, mail links.
53
54** [ssh]
55- =mode= — =embedded= | =system= (above).
56- =port= (22) — embedded listener port.
57- =host_keys= — list of private key paths; empty generates an ed25519
58 key at =<root>/ssh/host_ed25519=.
59
60** [http]
61- =addr= (=:443=), =tls= — =acme= | =files= | =off=.
62- =acme=: certificates via TLS-ALPN-01 on the HTTPS port, cached at
63 =<root>/acme=; =acme_email= for the CA account; =acme_http_addr=
64 (=:80=, ="off"= to disable) adds HTTP-01 and an https redirect —
65 failing to bind it is a warning, not fatal. Requires an =https://=
66 site_url with a public DNS name.
67- =files=: =cert_file= + =key_file=.
68- =off=: plain HTTP — development, or behind a TLS-terminating proxy.
69
70** [web]
71- =mode= — =view_only= (default) | =accounts=. In view_only the mutating
72 web routes are never registered; in accounts, browser sessions are
73 minted over SSH (=web login=), and users with write access can create
74 repos, comment, and make simple file edits (which commit unsigned,
75 honestly). =password_auth= is reserved and currently rejected.
76
77** [registration]
78- =mode= — =closed= (default) | =invite= | =open=. invite/open require
79 [mail]. See the user guide for the flows.
80
81** [mail]
82- =smtp_host= (host:port, 587 assumed), =from=, optional =smtp_user= /
83 =smtp_pass=. STARTTLS when offered. Required for invite/open
84 registration and self-service =email add=; in closed mode you may omit
85 it entirely and assert addresses by hand (below).
86
87** [api]
88- =enabled= (false) — the JSON API surface; see =docs/api.org=. Off
89 means no credential-bearing HTTP endpoint exists at all.
90
91** [webhooks]
92- =allow_local= (false) — permit webhook targets on loopback/private
93 addresses. Leave off unless you know why you need it (SSRF).
94
95** [limits]
96- =clone_timeout= (3600s) — cap on =repo import= fetches.
97- =max_blob_bytes= (100MB) — cap on raw file serving over the web.
98- =max_pack_bytes=, =ssh_auth_rate= — reserved, not yet enforced.
99
100** [git_daemon]
101- =enabled= (false), =port= (9418) — the anonymous =git://= listener.
102 Serves only public repositories that additionally ran
103 =repo settings git-daemon <repo> on=.
104
105** [go_import]
106Vanity Go module paths, one per line: ="host/module" = "owner/repo"=.
107Requests with =?go-get=1= at or under the module path answer with the
108go-import meta tag pointing at the repository's HTTPS clone URL, so
109=go install host/module/cmd/...@latest= resolves. The repository should
110be public (the module path itself confirms it exists).
111
112* Users, email, invites
113
114#+begin_src sh
115gitbayd admin user create alice --key alice.pub --email a@example.org --verified [--admin]
116gitbayd admin email verify alice a@example.org # admin assertion, no SMTP needed
117gitbayd admin invite --email b@example.org # mails a code; prints it if no SMTP
118#+end_src
119
120"Verified" means SMTP-confirmed or host-admin-asserted; the database
121records which. Verified emails are what make commit signatures
122meaningful — an unverified address never produces a =verified= badge.
123
124* Backup and restore
125
126#+begin_src sh
127gitbayd admin backup --out /var/backups/gitbay/backup.tar.gz
128#+end_src
129
130One archive: a consistent SQLite snapshot (taken *before* the
131repositories are read, so the database never references objects the
132archive missed), every repository, and the SSH host keys. Excluded:
133hook socket, regenerated hook scripts, WAL files. Safe to run against a
134live daemon.
135
136Restore: extract into an empty directory, point =server.root= at it,
137start gitbayd. Host keys are preserved, so clients keep their
138known_hosts entries; hooks regenerate at startup.
139
140* Upgrades
141
142Replace the binary, restart the unit. Migrations apply automatically and
143are transactional; hook scripts under =<root>/hooks= are rewritten at
144startup to point at the current binary path.
145
146* Odds and ends
147
148- deleting a fork marks MRs sourced from it =source_gone=; their diffs
149 remain viewable and mergeable because the target repo owns the
150 objects.
151- =refs/merge-requests/*= is server-owned and unpushable by clients.
152- audit-relevant activity (issue/MR lifecycle, imports, pushes) lands in
153 the =events= table, which also feeds webhooks.
154- the daemon idles under 10MB RSS; the smallest VPS tier is adequate.