152 lines · 4474 bytes
1 # openhub
2
3 Minimal self-hosted git hosting with SSH key authentication. No passwords, no OAuth — just Ed25519 keys.
4
5 ## Features
6
7 - **SSH key auth** — signup, login, and push all use your existing SSH key
8 - **Git over SSH and HTTPS** — clone, fetch, and push with either protocol
9 - **Interactive SSH signup** — `ssh` in with an unregistered key to create an account
10 - **SSH repo management** — create, list, and delete repos over SSH
11 - **Web browsing** — browse users, repos, file trees, file contents, and commit logs
12 - **Invite-only** — signups require a single-use invite code
13 - **Quotas** — per-user repo limits and per-repo disk limits via a pre-receive hook
14 - **Single binary** — one Rust binary runs both the HTTP and SSH servers
15
16 ## Quick Start
17
18 ### Install the CLI
19
20 ```sh
21 curl -fsSL https://your-host/install.sh | sh
22 ```
23
24 This installs the `openhub` CLI, configures SSH (`~/.ssh/config`), and sets up the git credential helper.
25
26 ### Create an account
27
28 ```sh
29 # Interactive signup over SSH (easiest)
30 ssh git@your-host
31
32 # Or via CLI
33 openhub register
34 ```
35
36 ### Use it
37
38 ```sh
39 openhub login
40 openhub repo new my-project
41 openhub clone you/my-project
42 cd my-project
43 # ... make changes ...
44 git push
45 ```
46
47 ### SSH commands
48
49 ```sh
50 # Clone over SSH
51 git clone git@your-host:user/repo.git
52
53 # Manage repos
54 ssh git@your-host repo new my-project
55 ssh git@your-host repo list
56 ssh git@your-host repo delete my-project
57 ```
58
59 ## Architecture
60
61 ```
62 server/ Axum HTTP server + russh SSH server
63 cli/ openhub CLI (register, login, repo management, clone)
64 hook/ git pre-receive hook for repo size enforcement
65 scripts/ install.sh, git-credential-openhub
66 migrations/ SQLite schema
67 deploy/ systemd unit, setup script
68 ```
69
70 The server runs two listeners via `tokio::select!`:
71
72 - **HTTP** (default `:8080`) — API, git smart HTTP backend, web UI
73 - **SSH** (default `:22`) — git transport, repo commands, interactive signup
74
75 Git protocol is handled by the system `git-http-backend` (HTTP) and `git-upload-pack`/`git-receive-pack` (SSH). The Rust server handles auth, routing, and quotas.
76
77 ## Configuration
78
79 All config via environment variables:
80
81 | Variable | Default | Description |
82 |---|---|---|
83 | `OPENHUB_SITE_NAME` | `openhub` | Site name shown in UI and page titles |
84 | `OPENHUB_BIND` | `0.0.0.0:8080` | HTTP listen address |
85 | `OPENHUB_SSH_BIND` | `0.0.0.0:22` | SSH listen address |
86 | `OPENHUB_REPOS_ROOT` | `/srv/openhub/repos` | Bare git repos directory |
87 | `OPENHUB_DB_URL` | `sqlite:/srv/openhub/openhub.db` | SQLite database URL |
88 | `OPENHUB_SSH_HOST_KEY` | `/srv/openhub/ssh_host_ed25519_key` | SSH host key path (auto-generated) |
89 | `OPENHUB_ADMIN_KEY` | *(none)* | Bearer token for creating invites |
90 | `OPENHUB_MAX_REPOS_PER_USER` | `25` | Max repos per user |
91 | `OPENHUB_MAX_REPO_BYTES` | `52428800` | Max repo size in bytes (50 MiB) |
92 | `OPENHUB_MAX_PUSH_BYTES` | `10485760` | Max push request body (10 MiB) |
93 | `OPENHUB_HOOK_PATH` | `/usr/local/bin/git-quota-hook` | Path to pre-receive hook binary |
94 | `OPENHUB_GIT_HTTP_BACKEND` | `git-http-backend` | Path to git HTTP backend |
95
96 ## Deployment
97
98 ### Prerequisites
99
100 - Rust toolchain
101 - `git`, `sqlite3`, `git-http-backend` (from `git-core`)
102
103 ### Setup
104
105 ```sh
106 # Run the setup script (creates user, disk image, builds, installs)
107 sudo deploy/setup.sh
108
109 # Create an admin key for generating invites
110 echo 'OPENHUB_ADMIN_KEY=your-secret-key' >> /srv/openhub/openhub.env
111
112 # Start
113 sudo systemctl start openhub
114 ```
115
116 ### Docker
117
118 ```sh
119 docker compose up -d
120 ```
121
122 ### Generate invites
123
124 ```sh
125 curl -X POST https://your-host/api/admin/invites \
126 -H "Authorization: Bearer $OPENHUB_ADMIN_KEY"
127 ```
128
129 ## API
130
131 | Method | Path | Auth | Description |
132 |---|---|---|---|
133 | `POST` | `/api/signup` | - | Create account with SSH key + invite |
134 | `POST` | `/api/login/challenge` | - | Request login challenge nonce |
135 | `POST` | `/api/login/verify` | - | Verify signature, get bearer token |
136 | `POST` | `/api/repos` | Bearer | Create a repository |
137 | `GET` | `/api/repos/:user` | - | List user's repositories |
138 | `DELETE` | `/api/repos/:user/:repo` | Bearer | Delete a repository |
139 | `GET` | `/api/stats` | - | User/repo counts and recent repos |
140 | `POST` | `/api/admin/invites` | Admin | Generate invite code |
141
142 ## Building
143
144 ```sh
145 # SQLite DB needed for sqlx compile-time checks
146 sqlite3 /tmp/openhub_build.db < migrations/0001_init.sql
147 DATABASE_URL=sqlite:/tmp/openhub_build.db cargo build --release
148 ```
149
150 ## License
151
152 MIT