vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
| 1 | # Deploying Vole to a server |
| 2 | |
| 3 | Vole is one binary, one configuration file, and one directory of state. It needs |
| 4 | no database server, no cache, and no object store, so "deploying" means: get one |
| 5 | small machine, install the package, say what address people will reach it on, and |
| 6 | start it. |
| 7 | |
| 8 | These pages do that for you. The machine configures itself on its first boot from |
| 9 | a file you paste into the provider's console — no Terraform, no API token, and |
| 10 | nothing to install on your own computer except the shell you already have. |
| 11 | |
| 12 | | If you have… | Start here | |
| 13 | |---|---| |
| 14 | | A Hetzner Cloud account | [Hetzner Cloud](hetzner.md) | |
| 15 | | A DigitalOcean account | [DigitalOcean](digitalocean.md) | |
| 16 | | An AWS account | [AWS](aws.md) | |
| 17 | | Any other Ubuntu or Debian machine, or a machine you already have | [Any server](vps.md) | |
| 18 | |
| 19 | ## What you need |
| 20 | |
| 21 | - **A DNS name** you can point at the machine, such as `forge.example.com`. |
| 22 | Vole puts this in `public_url`, and browsers bind a passkey to that address, so |
| 23 | pick the name you intend to keep. |
| 24 | - **An SSH key.** It becomes the first account, and it is how you push. Any key |
| 25 | you already use with another forge works. |
| 26 | - **A package file.** Vole's releases are published on its own instance, at |
| 27 | [rodent.software/vole/releases](https://rodent.software/vole/releases). Open |
| 28 | the release you want and copy the URL of the file for your machine's |
| 29 | architecture: `…/vole/releases/<tag>/artifacts/vole_<version>-1_amd64.deb`, or |
| 30 | `arm64` instead of `amd64`. |
| 31 | |
| 32 | There is no container image. Vole is one process whose state is a directory on |
| 33 | local disk, so a container would add a layer without removing one, and it would |
| 34 | cost the service unit's hardening. If your machines are already managed by |
| 35 | Compose or Kubernetes, give the forge a small virtual machine of its own; the |
| 36 | first-boot file works there unchanged. |
| 37 | |
| 38 | ## What happens on first boot |
| 39 | |
| 40 | The machine installs the package, writes a configuration that answers on your |
| 41 | name, creates the first account as an instance admin, and starts the service. |
| 42 | That takes about two minutes. |
| 43 | |
| 44 | Vole then obtains its own TLS certificate, so there is no proxy to configure. The |
| 45 | certificate is requested the first time a browser arrives on the name, so the |
| 46 | first visit after DNS starts answering can take a few seconds; if it fails, wait a |
| 47 | minute and reload. |
| 48 | |
| 49 | When it is up: |
| 50 | |
| 51 | - `https://forge.example.com` is the forge. |
| 52 | - `ssh://git@forge.example.com:2222/` is where repositories are cloned from. |
| 53 | - The account you created is an instance admin. It has no passkey yet, so the |
| 54 | browser cannot sign it in until you issue one. From your laptop: |
| 55 | |
| 56 | ```sh |
| 57 | vole admin --remote ssh://git@forge.example.com:2222 account invite admin |
| 58 | ``` |
| 59 | |
| 60 | Keep that link private: it is the one thing that grants browser access. |
| 61 | |
| 62 | Your own shell access to the machine is on port 22 and stays useful for upgrades |
| 63 | and backups. Vole's Git over SSH is on port 2222 and is a separate listener. |
| 64 | |
| 65 | ## First boot happens once |
| 66 | |
| 67 | The file you paste configures the machine when it is created and then never |
| 68 | again. Editing it afterwards changes nothing — that is how cloud-init works, not a |
| 69 | limitation of these pages. |
| 70 | |
| 71 | To change something later, edit the instance's configuration and restart it: |
| 72 | |
| 73 | ```sh |
| 74 | sudo -e /etc/vole/vole.toml |
| 75 | sudo systemctl restart vole |
| 76 | ``` |
| 77 | |
| 78 | To change something the first boot did — the account name, the TLS arrangement — |
| 79 | create a new machine. That is cheap; the repositories come with a clone. |
| 80 | |
| 81 | ## CI is a second machine |
| 82 | |
| 83 | These guides create the forge. A runner — the machine that leases jobs and runs |
| 84 | them in containers — is a separate decision and a separate machine, because it |
| 85 | executes repository code and can read every secret a job declares. |
| 86 | |
| 87 | - [CI runners](runner.md) — creating one, registering it, and allowing it on a |
| 88 | repository |
| 89 | |
| 90 | ## Backups are still your job |
| 91 | |
| 92 | A cloud's daily snapshot is the fastest way to get a machine back after a bad |
| 93 | upgrade, and it is not a backup of the instance. Two of Vole's files must be kept |
| 94 | apart from any copy of the data directory: the SSH host key that people's clients |
| 95 | pin, and `secrets.key`, which unseals repository secrets. A copy that holds both |
| 96 | the data and that key is a copy of plaintext. |
| 97 | |
| 98 | The procedure that covers this is short, and worth running once before you trust |
| 99 | it: |
| 100 | |
| 101 | - [Operations § Back up an instance](../operations.md#back-up-an-instance) |
| 102 | - [Operations § Restore an instance](../operations.md#restore-an-instance) |
| 103 | |
| 104 | ## Upgrading |
| 105 | |
| 106 | The first boot is not configuration management. Upgrades are a package install on |
| 107 | the machine: |
| 108 | |
| 109 | - [Packages § Upgrading](../packaging.md#upgrading) |
| 110 | |
| 111 | `users.db` is migrated in place the first time a newer binary reads it, and that |
| 112 | migration cannot be undone, so take a backup first. |
| 113 | |
| 114 | ## The files behind these guides |
| 115 | |
| 116 | Everything the guides use lives under [`deploy/`](../../deploy/README.md) in this |
| 117 | repository: the two first-boot files and the renderer that fills them in. Read |
| 118 | them before you run them; they are short. |
| 119 |