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