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
 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# Access level for anonymous users. Options are: admin-access, read-write,
 94# read-only, 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# Customize repos 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    readme: docs/README.md
111  - name: Example Private Repo
112    repo: my-private-repo
113    private: true
114    note: "A private repo"
115
116# Authorized users. Admins have full access to all repos. Regular users
117# can read all repos and push to their collab-repos.
118users:
119  - name: Beatrice
120    admin: true
121    public-keys:
122      - ssh-rsa AAAAB3Nz...   # redacted
123      - ssh-ed25519 AAAA...   # redacted
124  - name: Frankie
125    collab-repos:
126      - my-public-repo
127      - my-private-repo
128    public-keys:
129      - ssh-rsa AAAAB3Nz...   # redacted
130      - ssh-ed25519 AAAA...   # redacted
131```
132
133When `soft serve` is run for the first time, it creates a configuration repo
134containing the main README displayed in the TUI as well as a config file for
135user access control.
136
137```
138git clone ssh://localhost:23231/config
139```
140
141The `config` repo is publicly writable by default, so be sure to setup your
142access as desired. You can also set the `SOFT_SERVE_INITIAL_ADMIN_KEY`
143environment variable before first run and it will restrict access to that
144initial public key until you configure things otherwise.
145If you're having trouble, make sure you have generated keys with `ssh-keygen`
146as configuration is not supported for keyless users.
147
148### Server Settings
149
150In addition to the Git-based configuration above, there are a few
151environment-level settings:
152
153* `SOFT_SERVE_PORT`: SSH listen port (_default 23231_)
154* `SOFT_SERVE_HOST`: Address to use in public clone URLs
155* `SOFT_SERVE_BIND_ADDRESS`: Network interface to listen on (_default 0.0.0.0_)
156* `SOFT_SERVE_KEY_PATH`: SSH host key-pair path (_default .ssh/soft_serve_server_ed25519_)
157* `SOFT_SERVE_REPO_PATH`: Path where repos are stored (_default .repos_)
158* `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.
159
160## Pushing (and creating!) repos
161
162You can add your Soft Serve server as a remote to any existing repo:
163
164```
165git remote add soft ssh://localhost:23231/REPO
166```
167
168After you’ve added the remote just go ahead and push. If the repo doesn’t exist
169on the server it’ll be created.
170
171```
172git push soft main
173```
174
175## The Soft Serve TUI
176
177<img src="https://stuff.charm.sh/soft-serve/soft-serve-tui-diff.png" width="750" alt="TUI example showing a diff">
178
179Soft Serve serves a TUI over SSH for browsing repos, viewing files and commits,
180and grabbing clone commands:
181
182```
183ssh localhost -p 23231
184```
185
186It's also possible to “link” to a specific repo:
187
188```
189ssh localhost -t -p 23231 REPO
190```
191
192You can use the `tab` key to move between the repo menu and a particular repo.
193When a repo is highlighted you can use the following keys for navigation:
194
195* `R` – View the project's README file
196* `F` – Navigate and view all of the files in the project
197* `C` – View the commit log for the repo
198* `B` – View branches and tags for the repo
199
200## The Soft Serve SSH CLI
201
202```sh
203$ ssh -p 23231 localhost help
204Soft Serve is a self-hostable Git server for the command line.
205
206Usage:
207  ssh -p 23231 localhost [command]
208
209Available Commands:
210  cat         Outputs the contents of the file at path.
211  git         Perform Git operations on a repository.
212  help        Help about any command
213  ls          List file or directory at path.
214  reload      Reloads the configuration
215
216Flags:
217  -h, --help   help for ssh
218
219Use "ssh -p 23231 localhost [command] --help" for more information about a command.
220```
221
222Soft Serve SSH CLI has the ability to print files and list directories, perform
223`git` operations on remote repos, and reload the configuration when necessary.
224
225To print a file tree for the project, just use the `list` command along with the
226repo name as the SSH command to your Soft Serve server:
227
228```sh
229ssh -p 23231 localhost ls soft-serve
230```
231
232From there, you can print individual files using the `cat` command:
233
234```sh
235ssh -p 23231 localhost cat soft-serve/cmd/soft/main.go
236```
237
238You can add the `-c` flag to enable syntax coloring and `-l` to print line
239numbers:
240
241```sh
242ssh -p 23231 localhost cat soft-serve/cmd/soft/main.go -c -l
243```
244
245You can also use the `git` command to perform Git operations on a repo such as changing the default branch name for instance:
246
247```sh
248ssh -p 23231 localhost git soft-serve symbolic-ref HEAD refs/heads/taco
249```
250
251Both `git` and `reload` commands need admin access to the server to work. So
252make sure you have added your key as an admin user, or you’re using `anon-access:
253admin-access` in the configuration.
254
255## Managing Repos
256
257`.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. 
258It's recommended to have a dedicated directory for your soft-serve repos and config.
259
260### Deleting a Repo
261
262To delete a repo from your soft serve server, you'll have to remove the repo from the .repos directory.
263
264### Renaming a Repo
265
266To rename a repo's display name in the menu, change its name in the config.yaml file for your soft serve server.
267By default, the display name will be the repository name. 
268
269## A note about RSA keys
270
271Unfortunately, due to a shortcoming in Go’s `x/crypto/ssh` package, Soft Serve
272does not currently support access via new SSH RSA keys: only the old SHA-1
273ones will work.
274
275Until we sort this out you’ll either need an SHA-1 RSA key or a key with
276another algorithm, e.g. Ed25519. Not sure what type of keys you have?
277You can check with the following:
278
279```
280$ find ~/.ssh/id_*.pub -exec ssh-keygen -l -f {} \;
281```
282
283If you’re curious about the inner workings of this problem have a look at:
284
285- https://github.com/golang/go/issues/37278
286- https://go-review.googlesource.com/c/crypto/+/220037
287- https://github.com/golang/crypto/pull/197
288
289## Feedback
290
291We’d love to hear your thoughts on this project. Feel free to drop us a note!
292
293* [Twitter](https://twitter.com/charmcli)
294* [The Fediverse](https://mastodon.technology/@charm)
295* [Slack](https://charm.sh/slack)
296
297## License
298
299[MIT](https://github.com/charmbracelet/soft-serve/raw/main/LICENSE)
300
301***
302
303Part of [Charm](https://charm.sh).
304
305<a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a>
306
307Charm热爱开源 • Charm loves open source