1Soft Serve
  2==========
  3
  4<p>
  5    <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>
  6    <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>
  7    <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>
  8    <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>
  9    <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>
 10</p>
 11
 12A tasty, self-hostable Git server for the command line. š¦
 13
 14<picture>
 15  <source media="(max-width: 750px)" srcset="https://stuff.charm.sh/soft-serve/soft-serve-demo.gif?0">
 16  <source media="(min-width: 750px)" width="750" srcset="https://stuff.charm.sh/soft-serve/soft-serve-demo.gif?0">
 17  <img src="https://stuff.charm.sh/soft-serve/soft-serve-demo.gif?0" alt="Soft Serve screencast">
 18</picture>
 19
 20* Configure with `git`
 21* Create repos on demand with `git push`
 22* Browse repos, files and commits with an SSH-accessible TUI
 23* TUI mouse support
 24* Print files over SSH with or without syntax highlighting and line numbers
 25* Easy access control
 26  - Allow/disallow anonymous access
 27  - Add collaborators with SSH public keys
 28  - Repos can be public or private
 29
 30## Where can I see it?
 31
 32Just run `ssh git.charm.sh` for an example. You can also try some of the following commands:
 33
 34```bash
 35# Jump directly to a repo in the TUI
 36ssh git.charm.sh -t soft-serve
 37
 38# Print out a directory tree for a repo
 39ssh git.charm.sh ls soft-serve
 40
 41# Print a specific file
 42ssh git.charm.sh cat soft-serve/cmd/soft/root.go
 43
 44# Print a file with syntax highlighting and line numbers
 45ssh git.charm.sh cat soft-serve/cmd/soft/root.go -c -l
 46```
 47
 48## Installation
 49
 50Soft Serve is a single binary called `soft`. You can get it from a package
 51manager:
 52
 53```bash
 54# macOS or Linux
 55brew tap charmbracelet/tap && brew install charmbracelet/tap/soft-serve
 56
 57# Arch Linux
 58pacman -S soft-serve
 59
 60# Nix
 61nix-env -iA nixpkgs.soft-serve
 62
 63# Debian/Ubuntu
 64echo "deb https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
 65curl https://repo.charm.sh/apt/gpg.key | sudo apt-key add -
 66sudo apt update && sudo apt install soft-serve
 67
 68# Fedora
 69echo '[charm]
 70name=Charm
 71baseurl=https://repo.charm.sh/yum/
 72enabled=1
 73gpgcheck=1
 74gpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo
 75sudo yum install soft-serve
 76```
 77
 78You can also download a binary from the [releases][releases] page. Packages are
 79available in Alpine, Debian, and RPM formats. Binaries are available for Linux,
 80macOS, and Windows.
 81
 82[releases]: https://github.com/charmbracelet/soft-serve/releases
 83
 84Or just install it with `go`:
 85
 86```bash
 87go install github.com/charmbracelet/soft-serve/cmd/soft@latest
 88```
 89
 90## Setting up a server
 91
 92Make sure `git` is installed, then run `soft`. Thatās it.
 93
 94A [Docker image][docker] is also available.
 95
 96[docker]: https://github.com/charmbracelet/soft-serve/blob/main/docker.md
 97
 98## Configuration
 99
100The Soft Serve configuration is simple and straightforward:
101
102```yaml
103# The name of the server to show in the TUI.
104name: Soft Serve
105
106# The host and port to display in the TUI. You may want to change this if your
107# server is accessible from a different host and/or port that what it's
108# actually listening on (for example, if it's behind a reverse proxy).
109host: localhost
110port: 23231
111
112# Access level for anonymous users. Options are: admin-access, read-write,
113# read-only, and no-access.
114anon-access: read-write
115
116# You can grant read-only access to users without private keys.
117allow-keyless: false
118
119# Customize repos in the menu
120repos:
121  - name: Home
122    repo: config
123    private: true
124    note: "Configuration and content repo for this server"
125  - name: Example Public Repo
126    repo: my-public-repo
127    private: false
128    note: "A publicly-accessible repo"
129    readme: docs/README.md
130  - name: Example Private Repo
131    repo: my-private-repo
132    private: true
133    note: "A private repo"
134
135# Authorized users. Admins have full access to all repos. Regular users
136# can read public repos and push to their collab-repos.
137
138# Authorized users. Admins have full access to all repos. Private repos are only
139# accessible by admins and collab users. Regular users can read public repos
140# based on your anon-access setting.
141users:
142  - name: Beatrice
143    admin: true
144    public-keys:
145      - ssh-rsa AAAAB3Nz...   # redacted
146      - ssh-ed25519 AAAA...   # redacted
147  - name: Frankie
148    collab-repos:
149      - my-public-repo
150      - my-private-repo
151    public-keys:
152      - ssh-rsa AAAAB3Nz...   # redacted
153      - ssh-ed25519 AAAA...   # redacted
154```
155
156When `soft serve` is run for the first time, it creates a configuration repo
157containing the main README displayed in the TUI as well as a config file for
158user access control.
159
160```
161git clone ssh://localhost:23231/config
162```
163
164The `config` repo is publicly writable by default, so be sure to setup your
165access as desired. You can also set the `SOFT_SERVE_INITIAL_ADMIN_KEY`
166environment variable before first run and it will restrict access to that
167initial public key until you configure things otherwise.
168If you're having trouble, make sure you have generated keys with `ssh-keygen`
169as configuration is not supported for keyless users.
170
171### Server Settings
172
173In addition to the Git-based configuration above, there are a few
174environment-level settings:
175
176* `SOFT_SERVE_PORT`: SSH listen port (_default 23231_)
177* `SOFT_SERVE_HOST`: Address to use in public clone URLs
178* `SOFT_SERVE_BIND_ADDRESS`: Network interface to listen on (_default 0.0.0.0_)
179* `SOFT_SERVE_KEY_PATH`: SSH host key-pair path (_default .ssh/soft_serve_server_ed25519_)
180* `SOFT_SERVE_REPO_PATH`: Path where repos are stored (_default .repos_)
181* `SOFT_SERVE_INITIAL_ADMIN_KEY`: The public key that will initially have admin access to repos (_default ""_). This must be set before `soft` runs for the first time and creates the `config` repo. If set after the `config` repo has been created, this setting has no effect.
182
183## Pushing (and creating!) repos
184
185You can add your Soft Serve server as a remote to any existing repo:
186
187```
188git remote add soft ssh://localhost:23231/REPO
189```
190
191After youāve added the remote just go ahead and push. If the repo doesnāt exist
192on the server itāll be created.
193
194```
195git push soft main
196```
197
198## The Soft Serve TUI
199
200<img src="https://stuff.charm.sh/soft-serve/soft-serve-demo-commit.png" width="750" alt="TUI example showing a diff">
201
202Soft Serve serves a TUI over SSH for browsing repos, viewing files and commits,
203and grabbing clone commands:
204
205```
206ssh localhost -p 23231
207```
208
209It's also possible to ālinkā to a specific repo:
210
211```
212ssh localhost -t -p 23231 REPO
213```
214
215You can copy text to your clipboard over SSH. For instance, you can press <kbd>c</kbd> on the highlighted repo in the menu to copy the clone command [^osc52].
216
217[^osc52]: Copying over SSH depends on your terminal support of OSC52.
218
219## The Soft Serve SSH CLI
220
221```sh
222$ ssh -p 23231 localhost help
223Soft Serve is a self-hostable Git server for the command line.
224
225Usage:
226  ssh -p 23231 localhost [command]
227
228Available Commands:
229  cat         Outputs the contents of the file at path.
230  git         Perform Git operations on a repository.
231  help        Help about any command
232  ls          List file or directory at path.
233  reload      Reloads the configuration
234
235Flags:
236  -h, --help   help for ssh
237
238Use "ssh -p 23231 localhost [command] --help" for more information about a command.
239```
240
241Soft Serve SSH CLI has the ability to print files and list directories, perform
242`git` operations on remote repos, and reload the configuration when necessary.
243
244To print a file tree for the project, just use the `list` command along with the
245repo name as the SSH command to your Soft Serve server:
246
247```sh
248ssh -p 23231 localhost ls soft-serve
249```
250
251From there, you can print individual files using the `cat` command:
252
253```sh
254ssh -p 23231 localhost cat soft-serve/cmd/soft/root.go
255```
256
257You can add the `-c` flag to enable syntax coloring and `-l` to print line
258numbers:
259
260```sh
261ssh -p 23231 localhost cat soft-serve/cmd/soft/root.go -c -l
262```
263
264You can also use the `git` command to perform Git operations on a repo such as changing the default branch name for instance:
265
266```sh
267ssh -p 23231 localhost git soft-serve symbolic-ref HEAD refs/heads/taco
268```
269
270Both `git` and `reload` commands need admin access to the server to work. So
271make sure you have added your key as an admin user, or youāre using `anon-access:
272admin-access` in the configuration.
273
274## Managing Repos
275
276`.repos` and `.ssh` directories are created when you first run `soft` at the paths specified for the `SOFT_SERVE_KEY_PATH` and `SOFT_SERVE_REPO_PATH` environment variables. 
277It's recommended to have a dedicated directory for your soft-serve repos and config.
278
279### Deleting a Repo
280
281To delete a repo from your soft serve server, you'll have to remove the repo from the .repos directory.
282
283### Renaming a Repo
284
285To rename a repo's display name in the menu, change its name in the config.yaml file for your soft serve server.
286By default, the display name will be the repository name. 
287
288## A note about RSA keys
289
290Unfortunately, due to a shortcoming in Goās `x/crypto/ssh` package, Soft Serve
291does not currently support access via new SSH RSA keys: only the old SHA-1
292ones will work.
293
294Until we sort this out youāll either need an SHA-1 RSA key or a key with
295another algorithm, e.g. Ed25519. Not sure what type of keys you have?
296You can check with the following:
297
298```
299$ find ~/.ssh/id_*.pub -exec ssh-keygen -l -f {} \;
300```
301
302If youāre curious about the inner workings of this problem have a look at:
303
304- https://github.com/golang/go/issues/37278
305- https://go-review.googlesource.com/c/crypto/+/220037
306- https://github.com/golang/crypto/pull/197
307
308## Feedback
309
310Weād love to hear your thoughts on this project. Feel free to drop us a note!
311
312* [Twitter](https://twitter.com/charmcli)
313* [The Fediverse](https://mastodon.technology/@charm)
314* [Slack](https://charm.sh/slack)
315
316## License
317
318[MIT](https://github.com/charmbracelet/soft-serve/raw/main/LICENSE)
319
320***
321
322Part of [Charm](https://charm.sh).
323
324<a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a>
325
326Charmēē±å¼ęŗ ⢠Charm loves open source