RustForge

rustforge

RustForge: the read-only, cgit-style git web host serving this site

rustforge / DEPLOY.md
4189 bytes · raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# Deploying RustForge

The RustForge container is a Debian 13 (trixie) Proxmox LXC on Hetzner:
`ssh -p 2222 rust@88.99.212.146`, private IP **172.16.10.10**.
RustForge listens on `0.0.0.0:8090` inside the container. TLS and the public ports
80/443 belong to a separate proxy-manager container (e.g. Nginx Proxy Manager).

## Proxy manager setting

Point the proxy host at:

```
http://172.16.10.10:8090
```

Scheme `http`, forward host `172.16.10.10`, port `8090`. Websockets and
caching are not needed. Leave request buffering off if you can, so large clones
stream. Once the domain exists, set `clone_base_url` in `/etc/rustforge/rustforge.toml`
(it's a TODO there) and run `sudo systemctl restart rustforge`.

## Layout on the server

| Path | What | Owner |
|------|------|-------|
| `/opt/rustforge/bin/rustforge` | the binary, built on the dev box (CSS is compiled in, no static files needed) | root, 755 |
| `/opt/rustforge/README.md` | docs | root |
| `/etc/rustforge/rustforge.toml` | config (from `deploy/rustforge.toml.example`) | root:rustforge, 640 |
| `/etc/systemd/system/rustforge.service` | unit (from `deploy/rustforge.service`) | root |
| `/srv/git/<name>.git` | bare mirrors that RustForge serves | rustforge:rustforge |

The service runs as the system user `rustforge` (no login shell, home `/srv/git`).
It has `Restart=on-failure` and a read-only view of the whole filesystem
(`ProtectSystem=strict`, `NoNewPrivileges`, `PrivateTmp`, no capabilities).
Logs go to `journalctl -u rustforge`.

Packages installed on the server: `git` (RustForge runs `git upload-pack` for
clones), `ca-certificates`, `rsync` (receiving end of the mirror sync), `curl`
(for checks), and `unattended-upgrades` (Debian security updates).

## First-time setup (already done)

```sh
sudo apt-get update && sudo apt-get install -y --no-install-recommends git ca-certificates rsync curl unattended-upgrades
sudo useradd --system --user-group --home-dir /srv/git --no-create-home --shell /usr/sbin/nologin rustforge
sudo install -d -m 755 -o rustforge -g rustforge /srv/git
```

## Updating RustForge

From the dev box (it never builds on the server):

```sh
scripts/deploy.sh            # build --release, copy binary + unit, restart
scripts/deploy.sh --config   # same, and overwrite /etc/rustforge/rustforge.toml from the example
```

## Syncing the repos

The working repos in `/workspace` must never get a git remote or be pushed
from (other agents work in them). `scripts/sync-mirrors.sh` publishes them
anyway:

1. It keeps a private bare mirror per repo in `/workspace/.rustforge-mirrors/<name>.git`
   (`git clone --mirror` once, then `git remote update --prune` *inside the mirror*).
   Only branches and tags are published.
2. It rsyncs the mirror over ssh to `/srv/git/<name>.git`, objects first and refs
   second, so a half-finished sync never points at missing objects. The
   server keeps its own `config` and `hooks`.
3. It runs `chown -R rustforge:rustforge` on the server.

```sh
scripts/sync-mirrors.sh              # all repos
scripts/sync-mirrors.sh rust-kernel  # just one
```

It is idempotent, so run it whenever you want the site updated (or from cron).
To add a repo, add `name=/path` to `REPOS` in the script and a `[[repo]]` entry
to `/etc/rustforge/rustforge.toml`, then restart rustforge. `/workspace/rustbelt-os` is
already in the list and is skipped until it exists.

## Checks

```sh
curl -s -o /dev/null -w '%{http_code}\n' localhost:8090/
git clone http://127.0.0.1:8090/rust-kernel /tmp/x
systemctl status rustforge
```

## History: rename from `forge` (Nov 2026)

The project started as `forge`. The rename to RustForge moved the following on the server:
`forge.service` → `rustforge.service`, `/opt/forge` → `/opt/rustforge`,
`/etc/forge/forge.toml` → `/etc/rustforge/rustforge.toml`, system user
`forge` → `rustforge`, and the served repo `rust-githost` → `rustforge`. The
old unit, binary, config, user and `/srv/git/rust-githost.git` were removed.
On the dev box the repo moved from `/workspace/rust-githost` (now a symlink)
to `/workspace/rustforge`, and the mirrors moved from `/workspace/.forge-mirrors`
to `/workspace/.rustforge-mirrors`.