summaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-02-14 07:56:22 -0800
committerbndw <ben@bdw.to>2026-02-14 07:56:22 -0800
commitf0dfabe5b7f1f8d23169c6e62a2f0c27bd6c5463 (patch)
treee1f3b1f32b4f810cf957fef53d8fcec4d1fead18 /cmd
parentf5b667c80e49117c94481d49c5b0c77dbcf2804a (diff)
Add cgit web interface for browsing repos
Adds cgit as a web frontend for browsing git repositories. Visiting the base domain now shows a cgit repo index with trees, commits, diffs, and blame views. Public repos (marked with git-daemon-export-ok) are browsable and cloneable over HTTPS. - Install cgit during host init - Configure cgit with dark theme and base domain integration - Add cgit CGI handler to base domain Caddyfile - Update README to emphasize git-centric workflow with cgit frontend
Diffstat (limited to 'cmd')
-rw-r--r--cmd/ship/host/init.go24
1 files changed, 20 insertions, 4 deletions
diff --git a/cmd/ship/host/init.go b/cmd/ship/host/init.go
index 0ec573c..cfa2795 100644
--- a/cmd/ship/host/init.go
+++ b/cmd/ship/host/init.go
@@ -153,18 +153,19 @@ func setupGitDeploy(client *ssh.Client, baseDomain string, hostState *state.Host
153 } 153 }
154 fmt.Println(" Docker installed") 154 fmt.Println(" Docker installed")
155 155
156 fmt.Println("-> Installing git and fcgiwrap...") 156 fmt.Println("-> Installing git, fcgiwrap, and cgit...")
157 if _, err := client.RunSudo("apt-get install -y git fcgiwrap"); err != nil { 157 if _, err := client.RunSudo("apt-get install -y git fcgiwrap cgit"); err != nil {
158 return fmt.Errorf("error installing git/fcgiwrap: %w", err) 158 return fmt.Errorf("error installing git/fcgiwrap/cgit: %w", err)
159 } 159 }
160 // Allow git-http-backend (runs as www-data) to access repos owned by git. 160 // Allow git-http-backend (runs as www-data) to access repos owned by git.
161 // Scoped to www-data only, not system-wide, to preserve CVE-2022-24765 protection. 161 // Scoped to www-data only, not system-wide, to preserve CVE-2022-24765 protection.
162 // www-data's home is /var/www; ensure it can write .gitconfig there. 162 // www-data's home is /var/www; ensure it can write .gitconfig there.
163 client.RunSudo("mkdir -p /var/www")
163 client.RunSudo("chown www-data:www-data /var/www") 164 client.RunSudo("chown www-data:www-data /var/www")
164 if _, err := client.RunSudo("sudo -u www-data git config --global --add safe.directory '*'"); err != nil { 165 if _, err := client.RunSudo("sudo -u www-data git config --global --add safe.directory '*'"); err != nil {
165 return fmt.Errorf("error setting git safe.directory: %w", err) 166 return fmt.Errorf("error setting git safe.directory: %w", err)
166 } 167 }
167 fmt.Println(" git and fcgiwrap installed") 168 fmt.Println(" git, fcgiwrap, and cgit installed")
168 169
169 fmt.Println("-> Creating git user...") 170 fmt.Println("-> Creating git user...")
170 // Create git user (ignore error if already exists) 171 // Create git user (ignore error if already exists)
@@ -261,6 +262,21 @@ git ALL=(ALL) NOPASSWD: \
261 } 262 }
262 fmt.Println(" base domain Caddy config written") 263 fmt.Println(" base domain Caddy config written")
263 264
265 fmt.Println("-> Writing cgit config...")
266 cgitrcContent, err := templates.CgitRC(map[string]string{
267 "BaseDomain": baseDomain,
268 })
269 if err != nil {
270 return fmt.Errorf("error generating cgitrc: %w", err)
271 }
272 if err := client.WriteSudoFile("/etc/cgitrc", cgitrcContent); err != nil {
273 return fmt.Errorf("error writing cgitrc: %w", err)
274 }
275 if err := client.WriteSudoFile("/opt/ship/cgit-header.html", templates.CgitHeader()); err != nil {
276 return fmt.Errorf("error writing cgit header: %w", err)
277 }
278 fmt.Println(" cgit config written")
279
264 fmt.Println("-> Starting Docker and fcgiwrap...") 280 fmt.Println("-> Starting Docker and fcgiwrap...")
265 if _, err := client.RunSudo("systemctl enable docker fcgiwrap"); err != nil { 281 if _, err := client.RunSudo("systemctl enable docker fcgiwrap"); err != nil {
266 return fmt.Errorf("error enabling services: %w", err) 282 return fmt.Errorf("error enabling services: %w", err)