rin
Public Open-source lightweight git hosting.
README.md · 228 lines · 11.0 KB
Raw
1 # Polar
2
3 **Lightweight self-hosted Git hosting in a single Go binary.**
4
5 Polar is a small, fast alternative to heavyweight Git servers: push over HTTP, browse code, file issues, open pull requests, and publish releases — all served from one static binary with an embedded SQLite database and no external runtime dependencies.
6
7 ## Highlights
8
9 - **One binary, zero dependencies** — `CGO_ENABLED=0` build, pure-Go SQLite (`modernc.org/sqlite`) in WAL mode, bare repositories stored on disk.
10 - **Git Smart HTTP** — anonymous read access for public repositories, token-authenticated push, per-user personal access tokens, and browser-assisted sign-in via the OAuth 2.0 Device Authorization Grant (RFC 8628).
11 - **Code browsing** — file tree, blob viewer with server-side syntax highlighting (Chroma), commit history, diffs, branches, tags, and zip archives. The **New file**, **New folder** and **Upload files** actions let you create or upload content right in the browser — changes are committed straight to the selected branch, no local checkout required.
12 - **Collaboration** — issues with comments and open/close state; pull requests with comments, approvals and change requests; forks with cross-fork pull requests; per-repository collaborators with read/write roles; and releases with changelogs.
13 - **Polished UI** — `html/template` + htmx, no SPA build step; Markdown rendered with Goldmark and sanitized with bluemonday; Hugeicons outline sprite; self-hosted Inter and JetBrains Mono fonts (Cyrillic subsets included).
14 - **Command palette** — press `Ctrl+K` / `Cmd+K` for quick navigation and actions.
15 - **Three themes** — Light (`#fff` background, `#111` foreground), Dark (`#111` background, `#fff` foreground), and System (follows the OS `prefers-color-scheme`). The choice is persisted in a `polar_theme` cookie so the server renders the correct `data-theme` on first paint — no flash of the wrong theme.
16 - **Bilingual interface** — Russian and English, with a configurable default language.
17 - **Profiles and repository identity** — avatars, profile READMEs, and full-width background images with a soft vignette in both light and dark themes. Repositories can use their own avatar.
18 - **Administration** — public, confirm-only, or closed registration; an approval queue; role management; and permanent deletion of accounts and repositories (including all on-disk data).
19 - **Practical security** — Argon2id password hashing, CSRF protection, rate-limited login and registration, session cookies, and revocable access tokens.
20
21 ## Quick Start
22
23 ### Build from source
24
25 Requirements: Go (version per `go.mod`) and `git` available on the host.
26
27 ```bash
28 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o polar ./cmd/polar
29 ./polar
30 ```
31
32 Polar starts on `0.0.0.0:3000` and keeps its data in `./data`. Open http://localhost:3000 and register — **the first registered account becomes the administrator**. After that, choose **Public Registration**, **Confirm-only Registration**, or **No Registration** in the admin panel. Confirm-only mode keeps new accounts pending until an administrator approves them.
33
34 ### Docker
35
36 ```bash
37 docker compose up -d
38 ```
39
40 Or without Compose:
41
42 ```bash
43 docker build -t polar .
44 docker run -d --name polar -p 3000:3000 -v "$PWD/data:/app/data" polar
45 ```
46
47 ### systemd
48
49 ```ini
50 # /etc/systemd/system/polar.service
51 [Unit]
52 Description=Polar Self-Hosted Git Server
53 After=network.target
54
55 [Service]
56 Type=simple
57 User=polar
58 Group=polar
59 WorkingDirectory=/var/lib/polar
60 ExecStart=/usr/local/bin/polar -config /etc/polar/polar.toml
61 Environment=POLAR_STORAGE_DATA_DIR=/var/lib/polar/data
62 Restart=on-failure
63
64 [Install]
65 WantedBy=multi-user.target
66 ```
67
68 ## Configuration
69
70 Polar runs with sensible defaults and no config file. To customize, copy `polar.example.toml` to `polar.toml` (auto-detected in the working directory) or pass `-config /path/to/polar.toml`. Every setting can also be provided through environment variables, which take precedence over the file.
71
72 ```toml
73 [server]
74 host = "0.0.0.0"
75 port = 3000
76 base_url = "http://localhost:3000"
77
78 [storage]
79 data_dir = "./data"
80
81 [auth]
82 registration_enabled = true
83
84 [landing]
85 enabled = true
86 default_lang = "en" # "en" or "ru"
87 ```
88
89 | Environment variable | Description | Default |
90 |---|---|---|
91 | `POLAR_SERVER_HOST` | HTTP listen host | `0.0.0.0` |
92 | `POLAR_SERVER_PORT` | HTTP listen port | `3000` |
93 | `POLAR_SERVER_BASE_URL` | Public URL used for clone links | `http://localhost:3000` |
94 | `POLAR_STORAGE_DATA_DIR` | Directory for the database and bare repositories | `./data` |
95 | `POLAR_AUTH_REGISTRATION_ENABLED` | Initial registration policy before the admin panel setting is stored (`false` means closed) | `true` |
96 | `POLAR_LANDING_ENABLED` | Serve the landing page at `/` | `true` |
97 | `POLAR_LANDING_DEFAULT_LANG` | Default UI language (`ru` or `en`) | `ru` |
98 | `POLAR_CONFIG` | Path to the configuration file | `polar.toml` if present |
99
100 Short aliases are also accepted: `POLAR_HOST`, `POLAR_PORT`, `POLAR_BASE_URL`, `POLAR_DATA_DIR`.
101
102 ## Git over HTTP
103
104 Clone a public repository:
105
106 ```bash
107 git clone http://localhost:3000/rin/demo.git
108 ```
109
110 Push using a personal access token (create one in **Settings → Access tokens**; it is shown once and looks like `polar_...`):
111
112 ```bash
113 git clone http://localhost:3000/rin/demo.git
114 cd demo
115 git remote set-url origin http://rin:polar_XXXXXXXXXX@localhost:3000/rin/demo.git
116 git push
117 ```
118
119 When git asks for credentials, use your username as the login and the token as the password. Tokens can be revoked at any time from the settings page.
120
121 ### Browser-assisted sign-in (device flow)
122
123 Instead of pasting a token, let the bundled credential helper obtain one through your browser. Polar implements the OAuth 2.0 Device Authorization Grant (RFC 8628):
124
125 1. `git push` asks for credentials; the helper requests a device code from `POST /api/v1/device/code`.
126 2. It opens `{base_url}/login/device?user_code=XXXX-XXXX` in your browser — sign in and approve (or deny) the request.
127 3. The helper polls `POST /api/v1/device/token`, receives a personal access token, and caches it in `~/.polar/credentials.json`.
128
129 Register the helper once, pointing the path at your Polar checkout:
130
131 ```bash
132 # Linux / macOS
133 git config --global credential.helper '!sh /path/to/polar/scripts/git-credential-polar.sh'
134
135 # Windows (PowerShell)
136 git config --global credential.helper "!powershell -NoProfile -ExecutionPolicy Bypass -File C:/path/to/polar/scripts/git-credential-polar.ps1"
137 ```
138
139 Device codes expire after 15 minutes, are single-use, and the issued token can be revoked like any other. Set `POLAR_URL` to override the server address detected from the git remote.
140
141 ## Forks, Collaborators and Reviews
142
143 **Forks.** The **Fork** button on any repository page copies the project to your account. Forking a fork re-roots the copy to the upstream repository, and every fork records its origin — the repository page shows a `forked from` line linking back. If you already have a fork, the button takes you to it instead of creating a duplicate.
144
145 **Cross-fork pull requests.** Open a pull request from any branch of your fork into the base repository. The PR page marks the head repository, and merging a cross-fork pull request first fetches the head commits into the base repository, so no commits are lost.
146
147 **Collaborators.** Repository owners and instance administrators manage access in **Settings → Collaborators**: add any registered account with a `read` or `write` role, change roles, or remove access at any time.
148
149 **Reviews.** On an open pull request, reviewers submit an **Approve** or **Request changes** verdict — reviewing your own pull request is not allowed. Each reviewer has one current verdict, and the review panel lists them all.
150
151 ## Accounts and Administration
152
153 Administrators can switch registration between **Public Registration**, **Confirm-only Registration**, and **No Registration** at any time. Confirm-only accounts cannot sign in until approved from the admin panel.
154
155 Deleting an account from **Settings → Delete account** or from the admin panel permanently removes the user, all repositories they own, uploaded release assets, sessions, and repository files on disk. The last administrator account is protected from deletion. Repository deletion through the admin panel follows the same irreversible path.
156
157 ## Themes
158
159 Polar ships exactly three themes, selectable from the theme switcher (or the command palette):
160
161 | Theme | Background | Foreground |
162 |---|---|---|
163 | Light | `#fff` | `#111` |
164 | Dark | `#111` | `#fff` |
165 | System | follows the OS `prefers-color-scheme` | — |
166
167 The active theme is saved to `localStorage` and a `polar_theme` cookie, so the server renders `<html data-theme="...">` immediately and there is no flash of the wrong theme on load.
168
169 ## Project Layout
170
171 ```
172 polar/
173 ├── cmd/polar/main.go # Entry point, dependency wiring, graceful shutdown
174 ├── internal/
175 │ ├── config/ # polar.toml + POLAR_* environment overrides
176 │ ├── db/ # SQLite connection and migrations
177 │ ├── auth/ # Sessions, CSRF, Argon2id, access tokens
178 │ ├── user/ # User accounts and profiles
179 │ ├── repo/ # Repositories, issues, pull requests, releases
180 │ ├── git/ # Git plumbing (bare repos, commits, diffs)
181 │ ├── i18n/ # Russian and English message catalogs
182 │ └── web/
183 │ ├── handlers/ # HTTP and Git Smart HTTP handlers
184 │ ├── middleware/ # Auth, CSRF, rate limiting, i18n
185 │ ├── views/ # html/template views
186 │ └── static/ # go:embed assets (CSS, JS, fonts, icons)
187 ├── assets/input.css # Tailwind source for the generated stylesheet
188 ├── scripts/ # git credential helpers (device-flow sign-in)
189 ├── polar.example.toml
190 ├── Makefile
191 ├── Dockerfile
192 └── docker-compose.yml
193 ```
194
195 ## Development
196
197 ```bash
198 make dev # run locally
199 make test # go test ./...
200 make lint # go vet ./...
201 make build # static binary with -trimpath -ldflags="-s -w"
202 make build-all # cross-compile Linux/macOS/Windows binaries into dist/
203 make css # rebuild internal/web/static/css/app.css (requires the Tailwind CLI)
204 ```
205
206 All runtime assets are embedded with `go:embed` — the binary needs no external CDN or asset directory. See `THIRD_PARTY.md` for licenses of bundled assets (Hugeicons icons, Inter and JetBrains Mono fonts, htmx) and Go dependencies.
207
208 ## Data and Backups
209
210 ```
211 data/
212 ├── polar.db # SQLite database (WAL mode)
213 └── repos/ # Bare Git repositories, e.g. repos/rin/demo.git
214 ```
215
216 Safe backup while Polar is running:
217
218 ```bash
219 sqlite3 data/polar.db "VACUUM INTO 'data/polar-backup.db';"
220 tar -czf polar-backup-$(date +%F).tar.gz data/polar-backup.db data/repos/
221 rm data/polar-backup.db
222 ```
223
224 To restore, stop Polar, replace `data/polar.db` and `data/repos/` with the backup contents, and start it again.
225
226 ## Health Check
227
228 `GET /healthz` returns JSON with the database status — handy for Docker health checks and load balancers.