The built-in git server, and choosing another forge
Every Studio install brings its own git server, Gitea. Start it, serve it over TLS, or point Studio at your own Gitea or at GitHub instead.
Every Studio install brings up its own git server — Gitea, the default forge. You do not have to use it: you can point Studio at your own Gitea server, or at GitHub.
⚠ What is and is not proven. The start logic, the installer and the service plan are tested. Starting a real Gitea container, and running a real Gitea binary as a service, are not yet measured. Follow these steps on a machine you can afford to learn on first.
What you get
| Container install (every edition) | Native install (Team and Enterprise) | |
|---|---|---|
| How it runs | a container, started with saphan infra up gitea | a service beside the other Saphan services, registered by saphan service install |
| Where its data is | two named volumes: saphan-gitea-data (repositories) and saphan-gitea-config | <installation root>/gitea/, all mode 0700 |
| After a restart | comes back by itself | the same autostart rule as the other services |
| Listens on | forge.bundled_listen, default 127.0.0.1:3000 — loopback only | the same key and default |
| Pinned by | the image's SHA-256 digest | the release's checksum list, checked by the installer |
Gitea speaks plain HTTP, so a non-loopback forge.bundled_listen is refused
(forge-bundled-plain-http). To serve other machines, keep Gitea on loopback and put a TLS reverse
proxy in front of it (below).
Start it — container install
-
Put the deployment files on the machine (existing files are kept):
-
Start it (
--runtime podmanfor Podman):If it answers
this build carries no resolved digest, resolve one yourself and pass it in. An image that is not pinned by@sha256:is refused, because this server holds source code: -
Read the administrator's password. The login is
saphan-admin; the password is generated on the first start, kept on later ones, and never put in an environment variable, a command line or a log: -
Check it answers — a JSON body with a
version. The administrator account is created shortly after the server is healthy; give it a minute on the first start. -
To stop it without losing anything:
docker compose -f /opt/saphan/docker/saphan-gitea-compose.yml downkeeps both volumes. ⛔down -vdeletes the repositories.
Lost the administrator password? Keep the volumes, and run the same saphan infra up gitea
command again. If the password file is gone, the command sets a new password for the existing
administrator and writes it to the same file, without printing it.
Start it — native install
-
The installer places a
giteabinary beside the other programs when the release carries one, and says so when it does not. -
Register the services:
A machine-wide installation runs its services as root, and Gitea refuses to run as root, so name an unprivileged user with
--gateway-user <user>. Without one, the install printsNO GIT SERVER UNIT WAS REGISTEREDand why. -
Read the administrator password from the same file as above; the login is
saphan-admin. -
Upgrade. Installing a newer Studio installs the newer Gitea with it. The installer refuses to put an older Gitea over a newer one, because Gitea migrates its database forward and cannot migrate it back;
--allow-downgradeoverrides it, at your own risk. -
Uninstall.
saphan service uninstallremoves the services and keeps<root>/gitea/— those are your repositories. It prints the directory.
Serve it over TLS
-
Keep Gitea on loopback (
saphan config set forge.bundled_listen 127.0.0.1:3000). -
Point a DNS name at the machine, open TCP 80 and 443 for your proxy, and keep TCP 3000 closed to other machines. One Caddy configuration:
Caddyfile Any other TLS proxy works if it passes requests to
http://127.0.0.1:3000and forwards the originalHostand scheme. -
Tell Gitea its public address: for the container,
saphan infra up gitea --root-url https://git.example.com/; for the native install, setROOT_URLin<root>/gitea/custom/conf/app.iniand restart the service. Check withcurl -fsS https://git.example.com/api/v1/version.
Choose another forge
forge.kind takes bundled-gitea (the default for a new install), gitea or github.
Your own Gitea server (or one compatible with Gitea's API):
base_url carries the scheme and an explicit port. The token is never in the configuration:
token_lane names a lane whose credential is read when it is used. While forge.kind is not
bundled-gitea, saphan service install registers no git server.
GitHub: saphan config set forge.kind github, and the rest as above with base_url
https://api.github.com:443. ⚠ Saphan Studio reads GitHub and does not write to it — see
pull requests and forges.
Back to the bundled server: saphan config set forge.kind bundled-gitea. It needs no
base_url; until you bind a repository to it, it needs no repo, token_lane or enforcement.
When it refuses
| you see | meaning | do |
|---|---|---|
… carries no resolved digest | this build ships no image pin | pass --image …@sha256:<digest> |
--image … is not pinned by digest | the reference is a tag | give a digest-pinned reference |
… is not there — … saphan infra write | the compose file is not on this machine | run saphan infra write |
NO GIT SERVER UNIT WAS REGISTERED — no gitea binary … | the installed release carries no Gitea | use a release that carries one, or the container |
… a machine-wide installation runs its units as root … | Gitea refuses root | --gateway-user <user> |
this would replace gitea X with the older Y | a downgrade | do not, or pass --allow-downgrade |
forge-bundled-listen | forge.bundled_listen is not host:port | use host:port, port 1–65535 |
forge-bundled-plain-http | forge.bundled_listen is not a loopback address | keep it on loopback and use a TLS proxy |
Run Studio as containers
Run the Studio server — gateway, launcher, console server and CouchDB — as container images on volumes: first start, upgrade, roll back, and rotate the CouchDB administrator.
First run: setting the machine up at /setup
A machine with no owner is set up in a browser at /setup, or from a terminal with saphan install: the window, the screens, and the key that is shown once.