vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
|
b8e7a567
Keenan Nemetz
3d ago
|
1 | # Vole on any server |
| 2 | ||
|
942c93cd
Keenan Nemetz
3d ago
|
3 | This page is for a provider without its own guide — Vultr, Linode, Scaleway, OVH, |
| 4 | UpCloud, Proxmox — and for the machine you already have: a spare server, or a | |
| 5 | virtual machine on your own hardware. The first-boot file is the same one the | |
| 6 | [Hetzner](hetzner.md), [DigitalOcean](digitalocean.md), and [AWS](aws.md) guides | |
| 7 | paste into their consoles. | |
|
b8e7a567
Keenan Nemetz
3d ago
|
8 | |
| 9 | There are two ways, and the first one is less work. | |
| 10 | ||
| 11 | ## A machine that accepts user data | |
| 12 | ||
|
942c93cd
Keenan Nemetz
3d ago
|
13 | Most providers let you paste "user data", "cloud-init", or a "startup script" into |
| 14 | the form that creates a machine. Give it the rendered first-boot file and the machine configures | |
|
b8e7a567
Keenan Nemetz
3d ago
|
15 | itself. |
| 16 | ||
| 17 | Render it on your own computer. Pick `ubuntu-24.04` or `debian-13` as the image in | |
| 18 | the provider's form, and a size with 2 GB of memory and 20 GB of disk. | |
| 19 | ||
| 20 | ```sh | |
| 21 | cd deploy/cloud-init | |
| 22 | ||
| 23 | HOSTNAME=forge.example.com \ | |
| 24 | ADMIN_ACCOUNT=admin \ | |
| 25 | ADMIN_EMAIL=you@example.com \ | |
| 26 | ADMIN_SSH_KEY="$(cat ~/.ssh/id_ed25519.pub)" \ | |
|
b7396a11
Keenan Nemetz
2h ago
|
27 | VOLE_PACKAGE_URL=https://rodent.software/vole/releases/v0.2.0/artifacts/vole_0.2.0-1_amd64.deb \ |
|
b8e7a567
Keenan Nemetz
3d ago
|
28 | ./render.sh > user-data.yaml |
| 29 | ``` | |
| 30 | ||
| 31 | Paste the contents of `user-data.yaml` into the provider's field and create the | |
| 32 | machine. The values are: | |
| 33 | ||
| 34 | | Variable | What it is | | |
| 35 | |---|---| | |
| 36 | | `HOSTNAME` | The name people will reach the forge on. It becomes `public_url`, and passkeys bind to it, so choose the one you intend to keep | | |
| 37 | | `ADMIN_ACCOUNT` | Name of the first account, made an instance admin. Account names are permanent | | |
| 38 | | `ADMIN_SSH_KEY` | Public key of that account, as in the contents of `~/.ssh/id_ed25519.pub` | | |
|
b7396a11
Keenan Nemetz
2h ago
|
39 | | `VOLE_PACKAGE_URL` | The `.deb` for the machine's architecture, from [Vole's releases](https://rodent.software/vole/releases) | |
|
b8e7a567
Keenan Nemetz
3d ago
|
40 | | `ADMIN_EMAIL` | Contact address for the certificate authority. Optional, but a good idea | |
| 41 | | `INSTANCE_NAME` | What the landing page calls this forge. Default `Vole` | | |
| 42 | | `TLS_MODE` | `acme` (the default) lets Vole obtain its own certificate. `proxy` leaves TLS to a proxy you run, and serves plain HTTP on loopback | | |
| 43 | ||
| 44 | Point the name at the machine's address, then open `https://forge.example.com`. | |
| 45 | The certificate is issued on the first visit after DNS answers, so a first attempt | |
| 46 | that fails is usually just early; wait a minute and reload. | |
| 47 | ||
| 48 | `render.sh` needs `envsubst`, which is in `gettext-base` on Debian and Ubuntu or | |
| 49 | `gettext` elsewhere. Without it, edit `deploy/cloud-init/vole.yaml` by hand: each | |
| 50 | placeholder is a value with the same name. | |
| 51 | ||
| 52 | To issue the first passkey for the admin account, run this from your laptop: | |
| 53 | ||
| 54 | ```sh | |
| 55 | vole admin --remote ssh://git@forge.example.com:2222 account invite admin | |
| 56 | ``` | |
| 57 | ||
| 58 | ## A machine you configure yourself | |
| 59 | ||
| 60 | If the machine is already running and you have shell access, install the package | |
| 61 | and point it at your name. This is the same result the first-boot script | |
| 62 | produces, done by hand. | |
| 63 | ||
| 64 | ```sh | |
| 65 | # On the machine, as a user with sudo. | |
|
b7396a11
Keenan Nemetz
2h ago
|
66 | curl -fsSLO https://rodent.software/vole/releases/v0.2.0/artifacts/vole_0.2.0-1_amd64.deb |
|
b8e7a567
Keenan Nemetz
3d ago
|
67 | sudo apt install ./vole_0.2.0-1_amd64.deb |
| 68 | ``` | |
| 69 | ||
| 70 | The package creates the `vole` service account, `/var/lib/vole`, and an instance | |
| 71 | under the shipped configuration. Now write the configuration people will reach: | |
| 72 | ||
| 73 | ```toml | |
| 74 | # /etc/vole/vole.toml | |
| 75 | data_dir = "/var/lib/vole/data" | |
| 76 | ||
| 77 | http_addr = ":80" | |
| 78 | https_addr = ":443" | |
| 79 | public_url = "https://forge.example.com" | |
| 80 | acme_email = "you@example.com" | |
| 81 | ||
| 82 | ssh_addr = "0.0.0.0:2222" | |
| 83 | ``` | |
| 84 | ||
| 85 | Ports 80 and 443 are below 1024, and the packaged unit drops every capability, so | |
| 86 | grant the one that binds them: | |
| 87 | ||
| 88 | ```sh | |
| 89 | sudo install -d -m 0755 /etc/systemd/system/vole.service.d | |
| 90 | sudo tee /etc/systemd/system/vole.service.d/bind.conf >/dev/null <<'EOF' | |
| 91 | [Service] | |
| 92 | CapabilityBoundingSet=CAP_NET_BIND_SERVICE | |
| 93 | AmbientCapabilities=CAP_NET_BIND_SERVICE | |
| 94 | EOF | |
| 95 | ``` | |
| 96 | ||
| 97 | Then create the first account and start the service: | |
| 98 | ||
| 99 | ```sh | |
| 100 | sudo systemctl daemon-reload | |
| 101 | sudo -u vole vole admin --config /etc/vole/vole.toml \ | |
| 102 | account create admin --key /tmp/your-key.pub --role admin | |
| 103 | sudo systemctl enable --now vole | |
| 104 | ``` | |
| 105 | ||
| 106 | `--role admin` is what makes this account an instance admin. The first one has to | |
| 107 | be granted on the host; after that, admins can manage the instance over SSH with | |
| 108 | `vole admin --remote`. | |
| 109 | ||
| 110 | If you would rather run a proxy than let Vole hold the certificate, leave | |
| 111 | `https_addr` empty, set `http_addr = "127.0.0.1:8080"`, and name the header your | |
| 112 | proxy sets with the client address: | |
| 113 | ||
| 114 | ```toml | |
| 115 | git_http_client_ip_header = "X-Forwarded-For" | |
| 116 | ``` | |
| 117 | ||
| 118 | ## Then | |
| 119 | ||
| 120 | - [Deploying Vole](README.md) — backups, upgrades, and what first boot does | |
| 121 | - [Packages](../packaging.md) — what the package installs, and how upgrades work | |
| 122 | - [Configuration](../configuration.md) — every setting, including limits and sites |