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.
Add automatic HTTPS with ACME
642e599466fe4f5066afdc9a24775694a52c9749 · Keenan Nemetz · 14d ago · parent 91e6a33a
docs/configuration.md +61−5
| @@ -41,9 +41,14 @@ vole admin user list | |||
| 41 | 41 | | Setting | Default | What it does | | |
| 42 | 42 | |---|---:|---| | |
| 43 | 43 | | `data_dir` | `"./data"` | Where Vole keeps repositories, databases, stored files, and the audit log | | |
| 44 | | `http_addr` | `"127.0.0.1:8080"` | Address for the web interface and anonymous Git clone | | ||
| 44 | | `http_addr` | `"127.0.0.1:8080"` | Address for the web interface and anonymous Git clone; with `https_addr`, the ACME challenge and redirect address | | ||
| 45 | | `https_addr` | empty | Address for automatic HTTPS; setting it enables ACME | | ||
| 45 | 46 | | `ssh_addr` | `"127.0.0.1:2222"` | Address for SSH, the authenticated Git transport | | |
| 46 | 47 | | `public_url` | empty | Canonical browser address; must be HTTPS to enable passkey login | | |
| 48 | | `acme_email` | empty | Contact address given to the certificate authority | | ||
| 49 | | `acme_domains` | empty | Host names to obtain certificates for; defaults to the host in `public_url` | | ||
| 50 | | `acme_cache_dir` | `<data_dir>/acme` | Where the ACME account key and certificates are stored | | ||
| 51 | | `acme_directory_url` | Let's Encrypt production | ACME directory; use the staging URL or a private CA while testing | | ||
| 47 | 52 | | `dev_login` | empty | Development only: sign loopback browser requests in as this account | | |
| 48 | 53 | | `open_registration` | `false` | Let anyone create an account by registering a passkey; requires `public_url` to be HTTPS | | |
| 49 | 54 | | `max_blob_bytes` | `104857600` (100 MiB) | Largest single file accepted in a push | | |
| @@ -75,6 +80,56 @@ created. It is also the WebAuthn relying-party origin: browser login is enabled | |||
| 75 | 80 | only when `public_url` is an `https://` URL. Vole does not change how it routes | |
| 76 | 81 | requests based on this setting. | |
| 77 | 82 | ||
| 83 | ## Automatic HTTPS with ACME | ||
| 84 | |||
| 85 | Vole can obtain and renew its own TLS certificates, so a small public instance | ||
| 86 | does not need a proxy in front of it. Set `https_addr`, point the host name in | ||
| 87 | `public_url` at the server, and make both ports reachable: | ||
| 88 | |||
| 89 | ```toml | ||
| 90 | http_addr = ":80" | ||
| 91 | https_addr = ":443" | ||
| 92 | public_url = "https://forge.example.com" | ||
| 93 | acme_email = "admin@example.com" | ||
| 94 | ``` | ||
| 95 | |||
| 96 | `https_addr` turns it on, and `public_url` must then be an `https://` URL. Vole | ||
| 97 | serves the forge over TLS on that address. `http_addr` stops serving pages: it | ||
| 98 | answers ACME HTTP-01 challenges and redirects everything else to HTTPS. The | ||
| 99 | certificate host comes from `public_url`; to serve more than one name, list each | ||
| 100 | one in `acme_domains` (each host gets its own certificate): | ||
| 101 | |||
| 102 | ```toml | ||
| 103 | acme_domains = ["forge.example.com", "git.example.com"] | ||
| 104 | ``` | ||
| 105 | |||
| 106 | Certificates are obtained on first use and renewed in the background. Vole tries | ||
| 107 | tls-alpn-01 on port 443 and http-01 on port 80, so a network that blocks one can | ||
| 108 | still validate through the other. DNS must already point at the instance; ACME | ||
| 109 | cannot issue a name that does not resolve here. There is no wildcard support: | ||
| 110 | list concrete names, or keep a proxy for a wildcard certificate. | ||
| 111 | |||
| 112 | State lives in `data/acme/` by default. It contains the ACME account key, so the | ||
| 113 | directory is created private; back it up with the other instance data, though | ||
| 114 | losing it only means registering again and asking for new certificates. | ||
| 115 | |||
| 116 | While setting this up, use the staging directory so a mistake does not consume a | ||
| 117 | production rate limit: | ||
| 118 | |||
| 119 | ```toml | ||
| 120 | acme_directory_url = "https://acme-staging-v02.api.letsencrypt.org/directory" | ||
| 121 | ``` | ||
| 122 | |||
| 123 | Ports below 1024 need `CAP_NET_BIND_SERVICE`. The packaged systemd unit can grant | ||
| 124 | it; see [Packages](packaging.md). An instance with `https_addr` empty behaves as | ||
| 125 | before and leaves TLS to a proxy. | ||
| 126 | |||
| 127 | When `pages_domain` is also set, Vole obtains a certificate for a site host the | ||
| 128 | first time that host is requested, provided the repository exists and is | ||
| 129 | publicly readable. Site certificates therefore work with a wildcard DNS record | ||
| 130 | pointing at the instance, but they count against the certificate authority's | ||
| 131 | per-domain rate limit. | ||
| 132 | |||
| 78 | 133 | ## Open registration | |
| 79 | 134 | ||
| 80 | 135 | By default only an administrator can create an account. Set | |
| @@ -119,9 +174,9 @@ sign back in. Remove `dev_login` and restart to turn it off entirely. | |||
| 119 | 174 | ||
| 120 | 175 | ## Running behind a proxy | |
| 121 | 176 | ||
| 122 | Vole serves plain HTTP. If the instance is public, terminate TLS in a proxy in | ||
| 123 | front of `http_addr`. Keep the `Host` header intact: Vole uses it to decide which | ||
| 124 | site a request belongs to. | ||
| 177 | If a proxy already terminates TLS, leave `https_addr` empty. Vole serves plain | ||
| 178 | HTTP on `http_addr`; keep the `Host` header intact, because Vole uses it to | ||
| 179 | decide which site a request belongs to. | ||
| 125 | 180 | ||
| 126 | 181 | ```nginx | |
| 127 | 182 | server { | |
| @@ -148,6 +203,7 @@ connection intact. | |||
| 148 | 203 | | `data/runs.db` | The CI queue, finished-run index, and contributor-branch CI approvals. Partly rebuildable; deleting it loses pending work and approvals. | | |
| 149 | 204 | | `data/lfs/` | Stored large files, CI logs, and build artifacts. | | |
| 150 | 205 | | `data/audit.log` | A record of privileged actions. | | |
| 151 | | `data/ssh_host_ed25519_key` | The SSH host key. It is Vole's only long-term stored secret; browser credentials are public keys and session tokens are hashed. | | ||
| 206 | | `data/ssh_host_ed25519_key` | The SSH host key. It is the instance's long-term secret; browser credentials are public keys and session tokens are hashed. | | ||
| 207 | | `data/acme/` | The ACME account key and issued TLS certificates, when automatic HTTPS is enabled. | | ||
| 152 | 208 | ||
| 153 | 209 | See [Operations](operations.md) for backup and recovery. | |