Build a Private Git Server in 10 Minutes: A Soft Serve Practical Guide

2 views 0 likes 0 comments 21 minutesOriginalTutorial

Learn how to deploy Soft Serve, a lightweight, self-hosted Git server powered by SSH, in just 10 minutes. This guide covers installation, admin configuration, user management, and repository permissions for your team.

#Git Server # DevOps # SSH # Private Repository # Charmbracelet # Self-hosted # CLI Tool # Backend Infrastructure
Build a Private Git Server in 10 Minutes: A Soft Serve Practical Guide

Build a Private Git Server in 10 Minutes: A Soft Serve Practical Guide

Hi everyone. Over my years working as a Java backend developer, I often run into a specific scenario: our team has some internal utility scripts, configuration templates, or experimental projects that need a place to live. We want to host them, but we definitely don't want to push them to a public GitHub repository. Setting up GitLab is overkill—it devours memory and resources. Gitea is much lighter, but it still requires a database and web interface configuration. What if you could set a Git server up with a single command, using purely CLI interaction and managed entirely over SSH?

That's where I met Soft Serve. Brought to you by the Charmbracelet team (the creators of the beautiful Bubble Tea TUI library), Soft Serve is a self-hosted Git server written in Go. It runs as a single binary, managed entirely via SSH, and features a built-in TUI for browsing repositories right from your terminal. With nearly 7,000 stars, the community is active and growing.

In this tutorial, I'll walk you through deploying Soft Serve on a Linux server from scratch. We'll go through user creation, permission management, and setting up your first repository push. In just 10 minutes, you'll have a private Git server ready for production use.

Prerequisites

Before we start, ensure you have the following:

  • A Linux or macOS server (Ubuntu 20.04+ or CentOS 8+ recommended) to run the server.
  • Your local development machine has git installed and an SSH key generated (~/.ssh/id_ed25519.pub).
  • git installed on the server (apt install git or yum install git).
  • Basic understanding of SSH operations and Git remote concepts.

Why Ed25519 Keys? Soft Serve currently has a known limitation: Go's x/crypto/ssh package may struggle with newer RSA key formats. If you use newer RSA keys, SSH authentication might fail. Check your key type:

bash 复制代码
ssh-keygen -l -f ~/.ssh/id_ed25519.pub

Getting Started: 4 Steps to Go Live

Step 1: Install Soft Serve

Soft Serve is distributed as a single binary named soft. There are various ways to install it. On your server, I recommend using Go for maximum compatibility:

bash 复制代码
## Ensure Go is installed (1.19+)
go install github.com/charmbracelet/soft-serve/cmd/soft@latest

## After installation, move the binary to your PATH
sudo mv ~/go/bin/soft /usr/local/bin/

For macOS or Linux users who prefer Homebrew, it's even simpler:

bash 复制代码
brew install charmbracelet/tap/soft-serve

Debian/Ubuntu users can also use apt:

bash 复制代码
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
sudo apt update && sudo apt install soft-serve

Step 2: Initial Startup & Admin Configuration

This step is critical. On first startup, Soft Serve requires the environment variable SOFT_SERVE_INITIAL_ADMIN_KEYS to define the admin's SSH public key. This tells the system who has full control.

On your local machine, print your public key:

bash 复制代码
cat ~/.ssh/id_ed25519.pub

Copy the entire output (looking like ssh-ed25519 AAAA... user@host), then run the following on your server:

bash 复制代码
SOFT_SERVE_INITIAL_ADMIN_KEYS="paste-your-ssh-public-key-here" soft serve

Once started, you'll see output similar to:

复制代码
INFO Starting Soft Serve server...
INFO SSH listening on :23231
INFO HTTP listening on :23232

The service is now running. By default, Soft Serve stores all data (repos, keys, database) in a data/ directory. You can change this location using the SOFT_SERVE_DATA_PATH environment variable.

Why set the admin public key on first run? Soft Serve doesn't have a web registration page; everything is managed via SSH. The key provided here creates the admin user with full privileges. If you miss this step, recovering admin access requires manual config file edits, which is painful.

Step 3: Configure SSH Shortcut Access (Highly Recommended)

Typing ssh localhost -p 23231 -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes every time is tedious. Let's configure it.

Edit ~/.ssh/config on your local machine and add:

conf 复制代码
Host soft
  HostName your-server-ip-or-domain
  Port 23231
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes

Now you can simply run ssh soft. This isn't just about laziness—the git client also reads this configuration, allowing you to use shortcuts like git clone ssh://soft/repo-name later.

Step 4: Verify Connection

bash 复制代码
ssh soft help

You should see the command list, including subcommands like user, repo, and settings. The server setup is now complete.

Practical Example: Setting up Team Repositories

Let's imagine your team consists of three people: You (Admin), Beatrice (Developer), and Frankie (Developer). We need to create a private repository called backend-utils for collaboration.

1. Create Users

Connect as admin via ssh soft to create team members:

bash 复制代码
## Create users (defaults to read-only access)
ssh soft user create beatrice
ssh soft user create frankie

## Add Beatrice's SSH public key
ssh soft user add-pubkey beatrice "ssh-ed25519 AAAA... beatrice@laptop"

## Create Frankie and add key in one command
ssh soft user create frankie '-k "ssh-ed25519 AAAA... frankie@desktop"'

Note on Permissions: New users can only read public repositories by default. To get write access, they must be added as collaborators to specific repos.

2. Create Repository and Set Permissions

bash 复制代码
## Create a private repo (-p flag)
ssh soft repo create backend-utils -p \
  -d "Internal team utilities and shared components" \
  -n "Backend Utils"

As the admin, you have full access. Now, grant Beatrice and Frankie access:

bash 复制代码
## Add collaborators with read-write access
ssh soft repo collab add backend-utils beatrice read-write
ssh soft repo collab add backend-utils frankie read-write

## View collaborators
ssh soft repo collab list backend-utils

3. Push Code to the Repository

From any authorized machine, you operate just like GitHub:

bash 复制代码
## Clone (or add remote to an existing project)
git clone ssh://soft/backend-utils

cd backend-utils

## Standard development flow
echo "# Backend Utils" > README.md
git add .
git commit -m "init"
git push origin main

Don't want to clone first? You can add the remote to an existing local repo:

bash 复制代码
git remote add origin ssh://soft/backend-utils
git push origin main

Auto-creation feature: Soft Serve has a neat feature: if a remote repository doesn't exist, it automatically creates it on your first push. So, you can technically skip the repo create step and just git push.

4. Browse Repositories with TUI

bash 复制代码
ssh soft

You'll enter a beautiful terminal interface listing all repositories you can access. Use arrow keys to select repos, browse directory structures, view files with syntax highlighting, and copy clone commands. It's incredibly handy for quick code reviews or troubleshooting directly on the server.

Troubleshooting & Common Pitfalls

1. SSH RSA Key Authentication Failure

If ssh soft returns permission denied and you're sure the key is correct, check your key format. Soft Serve relies on Go's crypto/ssh library, which may not fully support newer RSA SHA-256 keys. Solution: Switch to an Ed25519 key (recommended) or use an older SHA-1 formatted RSA key.

2. Anonymous Access is Too Open

By default, anon-access is read-only, meaning anyone can git clone your public repos. While fine for intranets, if you expose this to the public internet, consider tightening it:

bash 复制代码
## Disable anonymous access
ssh soft settings anon-access no-access

## Or disallow keyless access
ssh soft settings allow-keyless false

3. Running in Production

soft serve runs in the foreground; closing the terminal stops the server. For production, use systemd. Soft Serve provides an official systemd configuration template. Once configured, manage it with systemctl start soft-serve.

4. Using PostgreSQL instead of SQLite?

SQLite is the default database and works fine for small teams. However, if you prefer PostgreSQL:

bash 复制代码
## Create database
psql -U postgres -c 'CREATE DATABASE soft_serve'

## Start with Postgres config
SOFT_SERVE_DB_DRIVER=postgres \
SOFT_SERVE_DB_DATA_SOURCE="postgres://postgres:password@localhost:5432/soft_serve?sslmode=disable" \
soft serve

5. Integrating CI/CD via Webhooks

Soft Serve supports repo-level webhooks for events like push, collaborators, and branch_tag_create. You can trigger Jenkins or GitHub Actions pipelines upon push:

bash 复制代码
ssh soft repo webhook create backend-utils \
  --url "https://jenkins.example.com/webhook/soft-serve" \
  --events push

Summary

We've successfully built a complete deployment chain using Soft Serve: Installation → Admin Key Config → SSH Shortcut → Users & Repo Creation → Permissions → Push → TUI Browsing. All this without touching a browser, installing a heavy database, or writing Nginx configs. Just one binary + SSH keys.

Next Steps:

  • Explore Soft Serve's Git hooks. Add a hooks/post-receive script in the repo directory to automate deployments.
  • Try repo import --mirror to mirror a GitHub repo for offline backup.
  • If you use Docker, check the official docker.md for easier containerized deployment.

Soft Serve isn't meant to replace GitHub (no PR reviews or Issue tracking). However, it shines as internal code hosting, edge node deployment, or private experimental project management. If your needs are simply "push/pull, manage permissions, trigger webhooks," this is your solution.

If you run into any issues during setup, feel free to discuss them below. See you in the next one!

Last Updated:

Comments (0)

Post Comment

Loading...
0/500
Loading comments...