README.md

  1# Soft Serve
  2
  3<p>
  4    <img style="width: 451px" src="https://stuff.charm.sh/soft-serve/soft-serve-header.png?0" alt="A nice rendering of some melting ice cream with the words ā€˜Charm Soft Serve’ next to it"><br>
  5    <a href="https://github.com/charmbracelet/soft-serve/releases"><img src="https://img.shields.io/github/release/charmbracelet/soft-serve.svg" alt="Latest Release"></a>
  6    <a href="https://pkg.go.dev/github.com/charmbracelet/soft-serve?tab=doc"><img src="https://godoc.org/github.com/golang/gddo?status.svg" alt="GoDoc"></a>
  7    <a href="https://github.com/charmbracelet/soft-serve/actions"><img src="https://github.com/charmbracelet/soft-serve/workflows/build/badge.svg" alt="Build Status"></a>
  8    <a href="https://nightly.link/charmbracelet/soft-serve/workflows/nightly/main"><img src="https://shields.io/badge/-Nightly%20Builds-orange?logo=hackthebox&logoColor=fff&style=appveyor"/></a>
  9</p>
 10
 11A tasty, self-hostable Git server for the command line. šŸ¦
 12
 13<picture>
 14  <source media="(max-width: 750px)" srcset="https://stuff.charm.sh/soft-serve/soft-serve-demo.gif?0">
 15  <source media="(min-width: 750px)" width="750" srcset="https://stuff.charm.sh/soft-serve/soft-serve-demo.gif?0">
 16  <img src="https://stuff.charm.sh/soft-serve/soft-serve-demo.gif?0" alt="Soft Serve screencast">
 17</picture>
 18
 19- Super fast setup to get your repos hosted quickly
 20- Easy access control using SSH public keys
 21- Browse repos, files and commits with SSH-accessible TUI
 22- Clone repos over SSH, HTTP, or Git protocol
 23- Manage repos with SSH commands
 24- Create repos on demand with SSH or `git push`
 25- Public and private repo support
 26
 27## Where can I see it?
 28
 29Just run `ssh git.charm.sh` for an example. You can also try some of the following commands:
 30
 31```bash
 32# Jump directly to a repo in the TUI
 33ssh git.charm.sh -t soft-serve
 34
 35# Print out a directory tree for a repo
 36ssh git.charm.sh repo tree soft-serve
 37
 38# Print a specific file
 39ssh git.charm.sh repo blob soft-serve cmd/soft/root.go
 40
 41# Print a file with syntax highlighting and line numbers
 42ssh git.charm.sh repo blob soft-serve cmd/soft/root.go -c -l
 43```
 44
 45## Installation
 46
 47Soft Serve is a single binary called `soft`. You can get it from a package
 48manager:
 49
 50```bash
 51# macOS or Linux
 52brew tap charmbracelet/tap && brew install charmbracelet/tap/soft-serve
 53
 54# Arch Linux
 55pacman -S soft-serve
 56
 57# Nix
 58nix-env -iA nixpkgs.soft-serve
 59
 60# Debian/Ubuntu
 61sudo mkdir -p /etc/apt/keyrings
 62curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
 63echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
 64sudo apt update && sudo apt install soft-serve
 65
 66# Fedora/RHEL
 67echo '[charm]
 68name=Charm
 69baseurl=https://repo.charm.sh/yum/
 70enabled=1
 71gpgcheck=1
 72gpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo
 73sudo yum install soft-serve
 74```
 75
 76You can also download a binary from the [releases][releases] page. Packages are
 77available in Alpine, Debian, and RPM formats. Binaries are available for Linux,
 78macOS, and Windows.
 79
 80[releases]: https://github.com/charmbracelet/soft-serve/releases
 81
 82Or just install it with `go`:
 83
 84```bash
 85go install github.com/charmbracelet/soft-serve/cmd/soft@latest
 86```
 87
 88## Setting up a server
 89
 90Make sure `git` is installed, then run `soft serve`. That’s it.
 91
 92This will create a `data` directory that will store all the repos, ssh keys,
 93and database.
 94
 95To change the default data path use `SOFT_SERVE_DATA_PATH` environment variable.
 96
 97```sh
 98SOFT_SERVE_DATA_PATH=/var/lib/soft-serve soft serve
 99```
100
101When you run Soft Serve for the first time, make sure you have the
102`SOFT_SERVE_INITIAL_ADMIN_KEY` environment variable is set to your ssh
103authorized key. Any added key to this variable will be treated as admin with
104full privileges.
105
106Using this environment variable, Soft Serve will create a new `admin` user that
107has full privileges. You can rename and change the user settings later.
108
109### Server Settings
110
111Once you start the server for the first time, the settings will be in
112`config.yaml` under your data directory. The default `config.yaml` is
113self-explanatory and will look like this:
114
115```yaml
116# Soft Serve Server configurations
117
118# The name of the server.
119# This is the name that will be displayed in the UI.
120name: "Soft Serve"
121
122# The SSH server configuration.
123ssh:
124  # The address on which the SSH server will listen.
125  listen_addr: ":23231"
126
127  # The public URL of the SSH server.
128  # This is the address that will be used to clone repositories.
129  public_url: "ssh://localhost:23231"
130
131  # The path to the SSH server's private key.
132  key_path: "ssh/soft_serve_host"
133
134  # The path to the SSH server's client private key.
135  # This key will be used to authenticate the server to make git requests to
136  # ssh remotes.
137  client_key_path: "ssh/soft_serve_client"
138
139  # The path to the SSH server's internal api private key.
140  internal_key_path: "ssh/soft_serve_internal"
141
142  # The maximum number of seconds a connection can take.
143  # A value of 0 means no timeout.
144  max_timeout: 0
145
146  # The number of seconds a connection can be idle before it is closed.
147  idle_timeout: 120
148
149# The Git daemon configuration.
150git:
151  # The address on which the Git daemon will listen.
152  listen_addr: ":9418"
153
154  # The maximum number of seconds a connection can take.
155  # A value of 0 means no timeout.
156  max_timeout: 0
157
158  # The number of seconds a connection can be idle before it is closed.
159  idle_timeout: 3
160
161  # The maximum number of concurrent connections.
162  max_connections: 32
163
164# The HTTP server configuration.
165http:
166  # The address on which the HTTP server will listen.
167  listen_addr: ":8080"
168
169  # The path to the TLS private key.
170  tls_key_path: ""
171
172  # The path to the TLS certificate.
173  tls_cert_path: ""
174
175  # The public URL of the HTTP server.
176  # This is the address that will be used to clone repositories.
177  # Make sure to use https:// if you are using TLS.
178  public_url: "http://localhost:8080"
179
180# The stats server configuration.
181stats:
182  # The address on which the stats server will listen.
183  listen_addr: ":8081"
184```
185
186You can also use environment variables, to override these settings. All server
187settings environment variables start with `SOFT_SERVE_` followed by the setting
188name all in uppercase. Here are some examples:
189
190- `SOFT_SERVE_NAME`: The name of the server that will appear in the TUI
191- `SOFT_SERVE_SSH_LISTEN_ADDR`: SSH listen address
192- `SOFT_SERVE_SSH_KEY_PATH`: SSH host key-pair path
193- `SOFT_SERVE_HTTP_LISTEN_ADDR`: HTTP listen address
194- `SOFT_SERVE_HTTP_PUBLIC_URL`: HTTP public URL used for cloning
195- `SOFT_SERVE_GIT_MAX_CONNECTIONS`: The number of simultaneous connections to git daemon
196
197A [Docker image][docker] is also available.
198
199[docker]: https://github.com/charmbracelet/soft-serve/blob/main/docker.md
200
201## Configuration
202
203Configuring Soft Serve is simple and straightforward. Use the SSH command-line
204interface to manage access settings, users, and repos.
205
206For more info try `ssh localhost -p 23231 help`. Make sure you use your key
207here.
208
209### Access Levels
210
211Soft Serve offers a simple access control. Users can have one of four access
212levels:
213
214`admin-access` has full control of the server and can make changes to users and repos.
215
216`read-write` access gets full control of repos.
217
218`read-only` can read public repos.
219
220`no-access` denies access to all repos.
221
222### Authentication
223
224Everything that needs authentication is done using SSH.
225
226By default, Soft Serve gives ready-only permission to anonymous connections to
227any of the above protocols. This is controlled by two settings `anon-access`
228and `allow-keyless`.
229
230- `anon-access`: Defines the access level for anonymous users. Available
231  options are `no-access`, `read-only`, `read-write`, and `admin-access`.
232  Default is `read-only`.
233- `allow-keyless`: Whether to allow connections that doesn't use keys to pass.
234  Setting this to `false` would disable access to SSH keyboard-interactive,
235  HTTP, and Git protocol connections. Default is `true`.
236
237```sh
238$ ssh localhost settings
239Manage server settings
240
241Usage:
242  ssh -p 23231 localhost settings [command]
243
244Available Commands:
245  allow-keyless Set or get allow keyless access to repositories
246  anon-access   Set or get the default access level for anonymous users
247
248Flags:
249  -h, --help   help for settings
250
251Use "ssh -p 23231 localhost settings [command] --help" for more information about a command.
252```
253
254> **Note** These settings can only be changed by admins.
255
256When `allow-keyless` is disabled, connections that don't use SSH public key
257authentication will get denied. This means cloning repos over HTTP(s) or git://
258will get denied.
259
260Meanwhile, `anon-access` controls the access level granted to connections that
261use SSH public key authentication but are not registered users. The default
262setting for this is `read-only`. This will grant anonymous connections that use
263SSH public key authentication `read-only` access to public repos.
264
265## Authorization
266
267Admins can manage users and manage their keys. Once a user is created and has
268access to the server, they can manage their own keys and settings.
269
270To create a new user simply use `user create`:
271
272```sh
273# Create a new user
274ssh -p 23231 localhost user create beatrice
275
276# Add user keys
277ssh -p 23231 localhost user add-pubkey beatrice ssh-rsa AAAAB3Nz...
278ssh -p 23231 localhost user add-pubkey beatrice ssh-ed25519 AAAA...
279
280# Create another user with public key
281ssh -p 23231 localhost user create frankie '-k "ssh-ed25519 AAAATzN..."'
282
283# Need help?
284ssh -p 23231 localhost user help
285```
286
287Once a user has access, they get `read-only` access to public repositories.
288They can also create new repositories on the server.
289
290Non-admin users can manage their keys using the `pubkey` command:
291
292```sh
293# List user keys
294ssh -p 23231 localhost pubkey list
295
296# Add key
297ssh -p 23231 localhost pubkey add ssh-ed25519 AAAA...
298
299# Wanna change your username?
300ssh -p 23231 localhost set-username yolo
301
302# To display user info
303ssh -p 23231 localhost info
304```
305
306## Repositories
307
308You can manage repositories using the `repo` command.
309
310```sh
311# Run repo help
312$ ssh -p 23231 localhost repo help
313Manage repositories
314
315Usage:
316  ssh -p 23231 localhost repo [command]
317
318Aliases:
319  repo, repos, repository, repositories
320
321Available Commands:
322  blob         Print out the contents of file at path
323  branch       Manage repository branches
324  collab       Manage collaborators
325  create       Create a new repository
326  delete       Delete a repository
327  description  Set or get the description for a repository
328  hide         Hide or unhide a repository
329  import       Import a new repository from remote
330  info         Get information about a repository
331  is-mirror    Whether a repository is a mirror
332  list         List repositories
333  private      Set or get a repository private property
334  project-name Set or get the project name for a repository
335  rename       Rename an existing repository
336  tag          Manage repository tags
337  tree         Print repository tree at path
338
339Flags:
340  -h, --help   help for repo
341
342Use "ssh -p 23231 localhost repo [command] --help" for more information about a command.
343```
344
345### Creating Repositories
346
347To create a repository, first make sure you are an admin or a registered user.
348Use the `repo create <repo>` command to create a new repository:
349
350```sh
351# Create a new repository
352ssh -p 23231 localhost repo create icecream
353
354# Create a repo with description
355ssh -p 23231 localhost repo create icecream '-d "This is an Ice Cream description"'
356
357# ... and project name
358ssh -p 23231 localhost repo create icecream '-d "This is an Ice Cream description"' '-n "Ice Cream"'
359
360# I need my repository private!
361ssh -p 23231 localhost repo create icecream -p '-d "This is an Ice Cream description"' '-n "Ice Cream"'
362
363# Help?
364ssh -p 23231 localhost repo create -h
365```
366
367Or you can add your Soft Serve server as a remote to any existing repo, given
368you have write access, and push to remote:
369
370```
371git remote add origin ssh://localhost:23231/icecream
372```
373
374After you’ve added the remote just go ahead and push. If the repo doesn’t exist
375on the server it’ll be created.
376
377```
378git push origin main
379```
380
381Repositories can be nested too:
382
383```sh
384# Create a new nested repository
385ssh -p 23231 localhost repo create charmbracelet/icecream
386
387# Or ...
388git remote add charm ssh://localhost:23231/charmbracelet/icecream
389git push charm main
390```
391
392### Deleting Repositories
393
394You can delete repositories using the `repo delete <repo>` command.
395
396```sh
397ssh -p 23231 localhost repo delete icecream
398```
399
400### Renaming Repositories
401
402Use the `repo rename <old> <new>` command to rename existing repositories.
403
404```sh
405ssh -p 23231 localhost repo rename icecream vanilla
406```
407
408### Repository Collaborators
409
410Sometimes you want to restrict write access to certain repositories. This can
411be achieved by adding a collaborator to your repository.
412
413Use the `repo collab <command> <repo>` command to manage repo collaborators.
414
415```sh
416# Add collaborator to soft-serve
417ssh -p 23231 localhost repo collab add soft-serve frankie
418
419# Remove collaborator
420ssh -p 23231 localhost repo collab remove soft-serve beatrice
421
422# List collaborators
423ssh -p 23231 localhost repo collab list soft-serve
424```
425
426### Repository metadata
427
428You can also change the repo's description, project name, whether it's private,
429etc using the `repo <command>` command.
430
431```sh
432# Set description for repo
433ssh -p 23231 localhost repo description icecream "This is a new description"
434
435# Hide repo from listing
436ssh -p 23231 localhost repo hidden icecream true
437
438# List repository info (branches, tags, description, etc)
439ssh -p 23231 localhost repo icecream info
440```
441
442To make a repository private, use `repo private <repo> [true|false]`. Private
443repos can only be accessed by admins and collaborators.
444
445```sh
446ssh -p 23231 localhost repo icecream private true
447```
448
449### Repository Branches & Tags
450
451Use `repo branch` and `repo tag` to list, and delete branches or tags. You can
452also use `repo branch default` to set or get the repository default branch.
453
454### Repository Tree
455
456To print a file tree for the project, just use the `repo tree` command along with
457the repo name as the SSH command to your Soft Serve server:
458
459```sh
460ssh -p 23231 localhost repo tree soft-serve
461```
462
463You can also specify the sub-path and a specific reference or branch.
464
465```sh
466ssh -p 23231 localhost repo tree soft-serve server/config
467ssh -p 23231 localhost repo tree soft-serve main server/config
468```
469
470From there, you can print individual files using the `repo blob` command:
471
472```sh
473ssh -p 23231 localhost repo blob soft-serve cmd/soft/root.go
474```
475
476You can add the `-c` flag to enable syntax coloring and `-l` to print line
477numbers:
478
479```sh
480ssh -p 23231 localhost repo blob soft-serve cmd/soft/root.go -c -l
481
482```
483
484Use `--raw` to print raw file contents. This is useful for dumping binary data.
485
486## The Soft Serve TUI
487
488<img src="https://stuff.charm.sh/soft-serve/soft-serve-demo-commit.png" width="750" alt="TUI example showing a diff">
489
490Soft Serve serves a TUI over SSH for browsing repos, viewing files and commits,
491and grabbing clone commands:
492
493```sh
494ssh localhost -p 23231
495```
496
497It's also possible to ā€œlinkā€ to a specific repo:
498
499```sh
500ssh -p 23231 localhost -t soft-serve
501```
502
503You can copy text to your clipboard over SSH. For instance, you can press
504<kbd>c</kbd> on the highlighted repo in the menu to copy the clone command
505[^osc52].
506
507[^osc52]:
508    Copying over SSH depends on your terminal support of OSC52. Refer to
509    [go-osc52](https://github.com/aymanbagabas/go-osc52) for more information.
510
511## A note about RSA keys
512
513Unfortunately, due to a shortcoming in Go’s `x/crypto/ssh` package, Soft Serve
514does not currently support access via new SSH RSA keys: only the old SHA-1
515ones will work.
516
517Until we sort this out you’ll either need an SHA-1 RSA key or a key with
518another algorithm, e.g. Ed25519. Not sure what type of keys you have?
519You can check with the following:
520
521```sh
522$ find ~/.ssh/id_*.pub -exec ssh-keygen -l -f {} \;
523```
524
525If you’re curious about the inner workings of this problem have a look at:
526
527- https://github.com/golang/go/issues/37278
528- https://go-review.googlesource.com/c/crypto/+/220037
529- https://github.com/golang/crypto/pull/197
530
531## Feedback
532
533We’d love to hear your thoughts on this project. Feel free to drop us a note!
534
535- [Twitter](https://twitter.com/charmcli)
536- [The Fediverse](https://mastodon.social/@charmcli)
537- [Discord](https://charm.sh/chat)
538
539## License
540
541[MIT](https://github.com/charmbracelet/soft-serve/raw/main/LICENSE)
542
543---
544
545Part of [Charm](https://charm.sh).
546
547<a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a>
548
549Charmēƒ­ēˆ±å¼€ęŗ • Charm loves open source