1Soft Serve
  2==========
  3
  4<p>
  5    <picture>
  6        <source srcset="https://stuff.charm.sh/soft-serve/soft-serve-header.webp?0" type="image/webp">
  7        <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">
  8    </picture><br>
  9    <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>
 10    <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>
 11    <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>
 12    <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>
 13</p>
 14
 15A tasty, self-hostable Git server for the command line. 🍦
 16
 17<img src="https://stuff.charm.sh/soft-serve/soft-serve-cli-demo.gif?0" width="750" alt="Soft Serve screencast">
 18
 19* Configure with `git`
 20* Create repos on demand with `git push`
 21* Browse repos, files and commits with an SSH-accessible TUI
 22* Print files over SSH with or without syntax highlighting and line numbers
 23* Easy access control
 24  - Allow/disallow anonymous access
 25  - Add collaborators with SSH public keys
 26  - Repos can be public or private
 27
 28## Where can I see it?
 29
 30Just run `ssh git.charm.sh` for an example. You can also try some of the following commands:
 31
 32```bash
 33# Jump directly to a repo in the TUI
 34ssh git.charm.sh -t soft-serve
 35
 36# Print out a directory tree for a repo
 37ssh git.charm.sh soft-serve
 38
 39# Print a specific file
 40ssh git.charm.sh soft-serve/cmd/soft/main.go
 41
 42# Print a file with syntax highlighting and line numbers
 43ssh git.charm.sh soft-serve/cmd/soft/main.go -c -l
 44```
 45
 46## Installation
 47
 48Soft Serve is a single binary called `soft`. You can get it from a package
 49manager:
 50
 51```bash
 52# macOS or Linux
 53brew tap charmbracelet/tap && brew install charmbracelet/tap/soft-serve
 54
 55# Arch Linux
 56pacman -S soft-serve
 57```
 58
 59You can also download a binary from the [releases][releases] page. Packages are
 60available in Alpine, Debian, and RPM formats. Binaries are available for Linux,
 61macOS, and Windows.
 62
 63[releases]: https://github.com/charmbracelet/soft-serve/releases
 64
 65Or just install it with `go`:
 66
 67```bash
 68go install github.com/charmbracelet/soft-serve/cmd/soft@latest
 69```
 70
 71## Setting up a server
 72
 73Make sure `git` is installed, then run `soft`. That’s it.
 74
 75A [Docker image][docker] is also available.
 76
 77[docker]: https://github.com/charmbracelet/soft-serve/blob/main/docker.md
 78
 79## Configuration
 80
 81The Soft Serve configuration is simple and straightforward:
 82
 83```yaml
 84# The name of the server to show in the TUI.
 85name: Soft Serve
 86
 87# The host and port to display in the TUI. You may want to change this if your
 88# server is accessible from a different host and/or port that what it's
 89# actually listening on (for example, if it's behind a reverse proxy).
 90host: localhost
 91port: 23231
 92
 93# The access level for anonymous users. Options are: read-write, read-only
 94# and no-access.
 95anon-access: read-write
 96
 97# You can grant read-only access to users without private keys.
 98allow-keyless: false
 99
100# Which repos should appear in the menu?
101repos:
102  - name: Home
103    repo: config
104    private: true
105    note: "Configuration and content repo for this server"
106  - name: Example Public Repo
107    repo: my-public-repo
108    private: false
109    note: "A publicly-accessible repo"
110  - name: Example Private Repo
111    repo: my-private-repo
112    private: true
113    note: "A private repo"
114
115# Authorized users. Admins have full access to all repos. Regular users
116# can read all repos and push to their collab-repos.
117users:
118  - name: Beatrice
119    admin: true
120    public-keys:
121      - ssh-rsa AAAAB3Nz...   # redacted
122      - ssh-ed25519 AAAA...   # redacted
123  - name: Frankie
124    collab-repos:
125      - my-public-repo
126      - my-private-repo
127    public-keys:
128      - ssh-rsa AAAAB3Nz...   # redacted
129      - ssh-ed25519 AAAA...   # redacted
130```
131
132When `soft` is run for the first time, it creates a configuration repo
133containing the main README displayed in the TUI as well as a config file for
134user access control.
135
136```
137git clone ssh://localhost:23231/config
138```
139
140The `config` repo is publicly writable by default, so be sure to setup your
141access as desired. You can also set the `SOFT_SERVE_INITIAL_ADMIN_KEY`
142environment variable before first run and it will restrict access to that
143initial public key until you configure things otherwise.
144If you're having trouble, make sure you have generated keys with `ssh-keygen`
145as configuration is not supported for keyless users.
146
147### Server Settings
148
149In addition to the Git-based configuration above, there are a few
150environment-level settings:
151
152* `SOFT_SERVE_PORT`: SSH listen port (_default 23231_)
153* `SOFT_SERVE_HOST`: Address to use in public clone URLs
154* `SOFT_SERVE_BIND_ADDRESS`: Network interface to listen on (_default 0.0.0.0_)
155* `SOFT_SERVE_KEY_PATH`: SSH host key-pair path (_default .ssh/soft_serve_server_ed25519_)
156* `SOFT_SERVE_REPO_PATH`: Path where repos are stored (_default .repos_)
157* `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.
158
159## Pushing (and creating!) repos
160
161You can add your Soft Serve server as a remote to any existing repo:
162
163```
164git remote add soft ssh://localhost:23231/REPO
165```
166
167After you’ve added the remote just go ahead and push. If the repo doesn’t exist
168on the server it’ll be created.
169
170```
171git push soft main
172```
173
174## The Soft Serve TUI
175
176<img src="https://stuff.charm.sh/soft-serve/soft-serve-tui-diff.png" width="750" alt="TUI example showing a diff">
177
178Soft Serve serves a TUI over SSH for browsing repos, viewing files and commits,
179and grabbing clone commands:
180
181```
182ssh localhost -p 23231
183```
184
185It's also possible to “link” to a specific repo:
186
187```
188ssh localhost -t -p 23231 REPO
189```
190
191You can use the `tab` key to move between the repo menu and a particular repo.
192When a repo is highlighted you can use the following keys for navigation:
193
194* `R` – View the project's README file
195* `F` – Navigate and view all of the files in the project
196* `C` – View the commit log for the repo
197* `B` – View branches and tags for the repo
198
199## Printing files over SSH
200
201<img src="https://stuff.charm.sh/soft-serve/soft-serve-cat-example.png?1" width="750" alt="Example tree and file output on the CLI">
202
203Soft Serve also has the ability to print files and directories directly from a
204remote repo without the need to clone or use the TUI.
205
206To print a file tree for the project, just use the repo name as the SSH command
207to your Soft Serve server:
208
209```
210ssh git.charm.sh soft-serve
211```
212
213From there you can print individual files:
214
215```
216ssh git.charm.sh soft-serve/cmd/soft/main.go
217```
218
219You can add the `-c` flag to enable syntax coloring and `-l` to print line
220numbers:
221
222```
223ssh git.charm.sh soft-serve/cmd/soft/main.go -c -l
224```
225
226### A note about RSA keys
227
228Unfortunately, due to a shortcoming in Go’s `x/crypto/ssh` package, Soft Serve
229does not currently support access via new SSH RSA keys: only the old SHA-1
230ones will work.
231
232Until we sort this out you'll either need an SHA-1 RSA key or a key with
233another algorithm, e.g. Ed25519. Not sure what type of keys you have?
234You can check with the following:
235
236```
237$ find ~/.ssh/id_*.pub -exec ssh-keygen -l -f {} \;
238```
239
240If you’re curious about the inner workings of this problem have a look at:
241
242- https://github.com/golang/go/issues/37278
243- https://go-review.googlesource.com/c/crypto/+/220037
244- https://github.com/golang/crypto/pull/197
245
246## Feedback
247
248We’d love to hear your thoughts on this project. Feel free to drop us a note!
249
250* [Twitter](https://twitter.com/charmcli)
251* [The Fediverse](https://mastodon.technology/@charm)
252* [Slack](https://charm.sh/slack)
253
254## License
255
256[MIT](https://github.com/charmbracelet/soft-serve/raw/main/LICENSE)
257
258***
259
260Part of [Charm](https://charm.sh).
261
262<a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a>
263
264Charm热爱开源 • Charm loves open source