diff options
| author | bndw <ben@bdw.to> | 2026-02-14 07:56:22 -0800 |
|---|---|---|
| committer | bndw <ben@bdw.to> | 2026-02-14 07:56:22 -0800 |
| commit | f0dfabe5b7f1f8d23169c6e62a2f0c27bd6c5463 (patch) | |
| tree | e1f3b1f32b4f810cf957fef53d8fcec4d1fead18 /cmd | |
| parent | f5b667c80e49117c94481d49c5b0c77dbcf2804a (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.go | 24 |
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) |
