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.
Sites
A website can be a branch. That keeps publishing simple and keeps the files with
the repository. Vole serves a repository’s pages branch at <repo>.<pages_domain>.
There is no build step on the server: change the branch and the next request sees
the new files.
Publish a build directory
Most websites are generated into a directory such as dist/. Vole can publish
that directory as a snapshot, so the branch contains exactly those files. If you
delete a page from the build, it stops being served.
npm run build
vole pages deploy dist # publish dist/ to the pages branch
vole pages deploy dist --dry-run # show changes without pushing
vole pages status # show the current branch and files
vole pages unpublish # take the site down
Publishing the same files twice does nothing. Use --branch if the instance
serves a different branch than pages.
Dotfiles such as .nojekyll and .well-known/ are published. Vole skips .git
and symbolic links. A site is just files, and a link pointing outside the build
directory would publish something you did not choose.
Publish by hand
Plain Git is enough:
git switch --orphan pages
printf '<h1>hello</h1>\n' > index.html
git add index.html
git commit -m "site"
git push origin pages # live at https://demo.pages.example.com/
Turn sites on
pages_domain = "pages.example.com" # <repo>.pages.example.com
pages_ref = "pages" # branch to serve
pages_procs = 4 # Git reader processes per active site
pages_cache_bytes = 33554432 # 32 MiB of cached files
Set pages_domain to enable websites. If you change pages_ref, pass the same
branch name to vole pages deploy --branch.
How sites are served
- A directory serves its
index.html. A directory URL without a trailing slash redirects to the version with one. - Vole uses the file’s Git hash as its
ETagand the commit time asLast-Modified, so unchanged pages return304. - Vole checks the branch and repository visibility once a second, so changes take effect within that window. The repository header links to the site only once the pages branch exists and the repository is public; until then there is no Site button, because the link would lead to a 404.
- A private repository has no public website. There is no logged-in reader, so the
site returns
404, just like its clone URL.
With automatic HTTPS enabled (https_addr), Vole obtains a certificate for each
site host the first time it is requested, as long as the repository exists and is
publicly readable. A wildcard DNS record pointing at the instance is enough;
wildcard certificates are not supported, so each host is issued separately. Without https_addr, terminate
TLS in a proxy in front of http_addr and keep the Host header: it is how Vole
knows which site was requested. See
Configuration § Automatic HTTPS with ACME
and Configuration § Running behind a proxy.
A workflow can publish the site as its last step. See Workflows § Publish a website.
Same-site risk
A site is content somebody else wrote, served from a hostname you control. If
pages_domain shares a registrable domain with the forge — forge.example.com
and *.pages.example.com, say — then every site is same-site with the forge,
and a malicious site can:
- make the browser send the forge’s
SameSite=Laxcookies on a top-level navigation (Vole’s writes still need a CSRF token, so this does not authorize anything on its own, but it is the assumption a weaker application would rely on); - open the forge in a window or frame and interact with it as a same-site
document, which is why
Cross-Origin-Opener-Policyand the CSP frame rules are set on every page; - share a cookie domain if you ever set one wider than a host.
Use a separate registrable domain for sites when the repositories publishing them
are not all trusted: pages.example.net for a forge at forge.example.com. The
two then cannot be same-site. If the sites are as trusted as the forge itself, a
subdomain is fine and keeps certificate management to one domain.