A lightweight Git forge that runs on the infrastructure you already have.

Repositories, merge requests, issues, wikis, releases and CI: one Rust binary and one PostgreSQL, nothing else to install. At rest, the server and its database use about 70 MiB of memory together.

Open FerrisGit
$docker compose up -d --build

No third-party account, no telemetry transmitted. See the architecture.

$ docker stats --no-stream measure-ferrisgit-server-1 measure-postgres-1
CONTAINER ID   NAME                         CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
04049f2efe20   measure-ferrisgit-server-1   0.00%     3.262MiB / 7.748GiB   0.04%     16.7kB / 65.4kB   0B / 0B           13
76c668d0c77c   measure-postgres-1           1.77%     66.21MiB / 7.748GiB   0.83%     66.3kB / 15.1kB   29.2MB / 55.3MB   13
An empty instance at rest: the stack of the docker-compose.yml file, version 0.1.2, measured with Docker on an Apple silicon Mac (arm64). Measurement method

Use cases

Four typical situations, and how FerrisGit answers each.

You host the code of a team or an association, and you do not want to dedicate a machine to the forge.
At rest the server uses a few MiB of memory and PostgreSQL about sixty. The server responds less than a second after it starts. It runs alongside the services already on the machine. Two things need backing up: the PostgreSQL database and one folder.
You want two-factor authentication not to depend on everyone's diligence.
It is mandatory for every account, with no setting to turn it off. At the first sign-in each person sets up a passkey or an authenticator app, and gets backup codes.
You hand the administration to someone, not everyone's code.
Administrators manage accounts, settings and runners. They cannot read other people's private repositories, through the interface or through Git: a test checks it.
Your CI has to run where you already have something to run it on.
A job runs in a Kubernetes Pod that the server creates itself, or in a Docker container through a lightweight runner. The pipeline is described in .ferrisgit-ci.yml, at the root of the repository.

Product overview

Excerpts of the actual interface, not mockups. The interface is in French for now; five languages are planned for 0.2.

The full feature list

Architecture

One process, five crates, a hexagonal layout: the domain knows nothing of the database, the adapters know nothing of the use cases.

The source on GitHub

Architecture of a FerrisGit instanceIsometric drawing. A Git client and a browser talk to one Rust binary, ferrisgit-api, made of the api, application, domain and infrastructure crates. The binary stores its data in PostgreSQL and in Git repositories on disk, and runs pipeline jobs either through a ferrisgit-runner on a Docker host or as Pods in a Kubernetes cluster. An orange line follows a push to its jobs. Seven numbered circles lead to the tiles of the page.api application domain infrastructure ferrisgit-runner ferrisgit-api: one binary ferrisgit-runner Git client HTTPS, username + token no SSH yet Browser signed in, or anonymous on public pages api REST API, Git over HTTP, web interface domain entities and ports, no I/O application use cases infrastructure adapters: PostgreSQL, git, Docker, Kubernetes, SMTP, webhooks PostgreSQL accounts, issues, pipelines; migrations run at startup Git repositories on disk, wikis included Docker host the runner polls every 5 s by default, one job at a time, in a container Kubernetes cluster one Pod per job, created by the server git push pipeline created jobs polls for jobs

Fig. 1 One instance. The orange line follows a push from the client to the jobs it starts.

  • request or storage
  • a push, to its jobs
  • the runner polls
  • a numbered tile of this page
  1. ferrisgit-domainEntities, value objects and the ports the rest depends on. No I/O.
  2. ferrisgit-applicationThe use cases. Depends on the domain only, tested against in-memory fakes.
  3. ferrisgit-infrastructureAdapters: PostgreSQL (sqlx), Git (gix and the git binary), SMTP, Kubernetes, Argon2, AES-GCM, JWT.
  4. ferrisgit-apiThe axum server: REST API under /api, Git smart HTTP, the Angular bundle. This is the binary.
  5. ferrisgit-runnerThe stand-alone Docker job runner.

What is missing today

Worth knowing before you deploy.

No SSH
Git goes over HTTP(S), with a token. There is no SSH access.
No protected branches
A Contributor can push to any branch. It is planned for 0.2.
The interface is in French only
The five languages are planned for 0.2. The documentation is in French.
No code analysis
Scans for secrets, dependencies and quality are on the roadmap. They are not in the product.

Outlook

Five versions, none shipped. Items are only ticked once they ship.

  1. 0.2Protected branches, checks, five languagesPlanned
  2. 0.3An analysis engine: secrets and dependenciesPlanned
  3. 0.4Quality gates and a dashboardPlanned
  4. 0.5Code quality: metrics, rules, coveragePlanned
  5. 0.6Security analysis and ArtiFerrisPlanned

Evaluate FerrisGit, then deploy your own instance.

The public instance lets you explore the product. Your own instance keeps your code.

Start the stack with Docker Compose
git clone https://github.com/Masmarino/FerrisGit.git
cd FerrisGit
cp .env.example .env
# set POSTGRES_PASSWORD, JWT_SECRET, SETTINGS_ENCRYPTION_KEY and the admin password in .env
docker compose up -d --build