just-use-git
Easily self-host and manage your own git server.
This project provides a CLI utility that builds and deploys a containerized git server
to a remote host. The deployed git server is composed of several services run by quadlet systemd units:
ssdh - Allows pushing to the git server via SSH and running limited git-shell commands.
fcgi - Runs the backend CGI layer (cgit and git-http-backend).
caddy - TLS termination, HTTP clone, and the cgit web frontend.
The CLI utility also provides commands for managing repositories on the git server.
Installation
go install git.dick.codes/just-use-git/cmd/jugctl@latest
This installs the jugctl binary to $(go env GOPATH)/bin — make
sure that's on your PATH.
Server management
jugctl server init
Gathers a server's configuration, validates it, checks the remote host
meets jugctl's prerequisites (see docs/bootstrap.md
for what's checked, including DNS setup), and saves the result so later
commands can refer to it with --server. It does not render or deploy
anything.
jugctl server init \
--name home \
--git-host git.example.com \
--web-host web.example.com \
--service-user deploy \
--service-identity-file ~/.ssh/deploy_ed25519 \
--git-identity-file ~/.ssh/git_ed25519 \
--acme-email admin@example.com \
--authorized-key-file ~/.ssh/git_ed25519.pub
Any flag left unset is prompted for interactively. Re-running jugctl server init --name home ... later overwrites the saved home server. Flags:
--host — SSH address to check, if different from --git-host (e.g. a raw IP before DNS is live)
--name — friendly name used to refer to this server later
--git-host — hostname clients use to clone over SSH/HTTPS
--web-host — hostname Caddy serves the cgit browsing UI on
--service-user — unprivileged account on the host that owns the rootless pod
--service-port — SSH port the service user's sshd listens on (default 2022)
--service-identity-file — SSH private key for the service user
--git-user — account the container's sshd exposes for git-shell operations (default git)
--git-port — SSH port the container's sshd listens on (default 22)
--git-identity-file — SSH private key for the git user
--acme-email — contact email Caddy registers with Let's Encrypt
--cgit-title / --cgit-description — optional cgit branding
--default-branch — default branch new repositories are created with (default main)
--authorized-key-file — path to a public key file to authorize for the git user (repeatable)
--image — just-use-git container image reference (usually set later by jugctl server build, which persists the tag it builds)
jugctl server build
Resolves a server previously saved with jugctl server init, streams the
embedded just-use-git image build context to its host over SSH, and
runs podman build there — the host-side build described in
docs/deployment.md, automated. Unless
--no-persist is passed, the resulting tag is saved into the server's
config so a subsequent jugctl server deploy picks it up with no --image
override.
jugctl server build --server home
Flags:
--server — friendly name of the saved server to build on (prompts to pick one if omitted and multiple are saved)
--host — SSH address to build on, if different from --git-host (e.g. a raw IP before DNS is live)
--platform — target platform passed to podman build (default linux/amd64)
--tag — image tag to build and persist (default localhost/just-use-git:dev)
--no-persist — don't save the built tag into the server's config
jugctl server deploy
Resolves a server previously saved with jugctl server init, renders the
just-use-git quadlet units, writes them onto the remote host over SSH
as an unprivileged service user, then starts (or restarts) the pod.
Safe to re-run against an already-deployed server — redeploying is
idempotent. See docs/deployment.md for the full
init-then-deploy walkthrough.
jugctl server deploy --server home
Flags:
--server — friendly name of the saved server to deploy (prompts to pick one if omitted and multiple are saved)
--host — SSH address to deploy to, if different from --git-host (e.g. a raw IP before DNS is live)
--image — override the container image reference for this deploy; the override is persisted back into the saved server
jugctl server update
Changes a saved server's cgit branding — the server-level root-title
and/or root-desc — and immediately redeploys so the change takes
effect. At least one of --title or --description is required;
passing an empty string clears that field.
jugctl server update --server home --title "home repos"
Flags:
--server — friendly name of the saved server to update (prompts to pick one if omitted and multiple are saved)
--title — new cgit root-title (empty string clears it)
--description — new cgit root-desc (empty string clears it)
jugctl server assets upload
Uploads custom cgit static assets (stylesheet, logo, favicon) onto a
deployed server's persistent caddy volume, overriding the image
defaults. At least one of --css, --logo, or --favicon must be
given.
jugctl server assets upload --server home --css ./cgit.css --logo ./logo.png
Flags:
--server — friendly name of the saved server (prompts to pick one if omitted and multiple are saved)
--css — path to a local cgit.css to upload
--logo — path to a local logo to upload (installed as cgit.png)
--favicon — path to a local favicon to upload (installed as favicon.ico)
jugctl server assets reset
Deletes selected custom cgit static assets from a deployed server and
restarts caddy so it re-seeds them from the image defaults. At least
one of --css, --logo, --favicon, or --all must be given.
jugctl server assets reset --server home --css
Flags:
--server — friendly name of the saved server (prompts to pick one if omitted and multiple are saved)
--css — reset cgit.css to the image default
--logo — reset the logo to the image default
--favicon — reset the favicon to the image default
--all — reset every custom asset to its image default
Repository management
jugctl repo create <name>
Creates a new bare repository named <name> on a saved server, via SSH
as the git user, and prints the resulting clone URL.
jugctl repo create myproject --server home --description "my project" --owner dick
Flags:
--server — friendly name of the saved server (prompts to pick one if omitted and multiple are saved)
--description — optional repository description
--owner — optional repository owner
If --description or --owner are omitted, you'll be prompted for
them interactively.
jugctl repo update <name>
Updates an existing bare repository named <name> on a saved server,
via SSH as the git user, touching only the fields given via
--name/--description/--owner. At least one of those flags must
be given. Renaming with --name moves the underlying bare repository
to its new path.
jugctl repo update myproject --server home --name renamed --description "new description"
Flags:
--server — friendly name of the saved server the repo lives on (prompts to pick one if omitted and multiple are saved)
--name — new name for the repository; moves the bare repo to the new path
--description — new repository description
--owner — new repository owner
jugctl repo destroy <name>
Permanently deletes an existing bare repository named <name> on a
saved server, via SSH as the git user. Prompts for a y/N confirmation
before deleting; anything other than y/yes aborts with no changes
made.
jugctl repo destroy myproject --server home
Flags:
--server — friendly name of the saved server the repo lives on (prompts to pick one if omitted and multiple are saved)
Contributing
Outside contributions to this project are not being solicited at this time.
Contact the maintainer via email if you wish to report a bug or request a feature.
Patches are accepted via git-send-mail.
Maintainer: Dick Davis
Building
make build
Running tests
make test
Linting
make vet
make fmt
Releasing
make release VERSION=vX.Y.Z
License
AGPLv3 or later. See LICENSE.