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