Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

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.

Code

395 commit(s) on main

update readme Keenan Nemetz · 30m ago 32290114
source preview history blame raw 4.2 KiB
1# Sites
2
3A website can be a branch. That keeps publishing simple and keeps the files with
4the repository. Vole serves a repository's `pages` branch at `<repo>.<pages_domain>`.
5There is no build step on the server: change the branch and the next request sees
6the new files.
7
8## Publish a build directory
9
10Most websites are generated into a directory such as `dist/`. Vole can publish
11that directory as a snapshot, so the branch contains exactly those files. If you
12delete a page from the build, it stops being served.
13
14```sh
15npm run build
16vole pages deploy dist # publish dist/ to the pages branch
17vole pages deploy dist --dry-run # show changes without pushing
18vole pages status # show the current branch and files
19vole pages unpublish # take the site down
20```
21
22Publishing the same files twice does nothing. Use `--branch` if the instance
23serves a different branch than `pages`.
24
25Dotfiles such as `.nojekyll` and `.well-known/` are published. Vole skips `.git`
26and symbolic links. A site is just files, and a link pointing outside the build
27directory would publish something you did not choose.
28
29## Publish by hand
30
31Plain Git is enough:
32
33```sh
34git switch --orphan pages
35printf '<h1>hello</h1>\n' > index.html
36git add index.html
37git commit -m "site"
38git push origin pages # live at https://demo.pages.example.com/
39```
40
41## Turn sites on
42
43```toml
44pages_domain = "pages.example.com" # <repo>.pages.example.com
45pages_ref = "pages" # branch to serve
46pages_procs = 4 # Git reader processes per active site
47pages_cache_bytes = 33554432 # 32 MiB of cached files
48```
49
50Set `pages_domain` to enable websites. If you change `pages_ref`, pass the same
51branch name to `vole pages deploy --branch`.
52
53## How sites are served
54
55- A directory serves its `index.html`. A directory URL without a trailing slash
56 redirects to the version with one.
57- Vole uses the file's Git hash as its `ETag` and the commit time as
58 `Last-Modified`, so unchanged pages return `304`.
59- Vole checks the branch and repository visibility once a second, so changes take
60 effect within that window. The repository header links to the site only once
61 the pages branch exists and the repository is public; until then there is no
62 Site button, because the link would lead to a 404.
63- A private repository has no public website. There is no logged-in reader, so the
64 site returns `404`, just like its clone URL.
65
66With automatic HTTPS enabled (`https_addr`), Vole obtains a certificate for each
67site host the first time it is requested, as long as the repository exists and is
68publicly readable. A wildcard DNS record pointing at the instance is enough;
69wildcard certificates are not supported, so each host is issued separately. Without `https_addr`, terminate
70TLS in a proxy in front of `http_addr` and keep the `Host` header: it is how Vole
71knows which site was requested. See
72[Configuration § Automatic HTTPS with ACME](configuration.md#automatic-https-with-acme)
73and [Configuration § Running behind a proxy](configuration.md#running-behind-a-proxy).
74
75A workflow can publish the site as its last step. See
76[Workflows § Publish a website](workflows.md#publish-a-website).
77
78## Same-site risk
79
80A site is content somebody else wrote, served from a hostname you control. If
81`pages_domain` shares a registrable domain with the forge — `forge.example.com`
82and `*.pages.example.com`, say — then every site is *same-site* with the forge,
83and a malicious site can:
84
85- make the browser send the forge's `SameSite=Lax` cookies on a top-level
86 navigation (Vole's writes still need a CSRF token, so this does not authorize
87 anything on its own, but it is the assumption a weaker application would rely on);
88- open the forge in a window or frame and interact with it as a same-site
89 document, which is why `Cross-Origin-Opener-Policy` and the CSP frame rules are
90 set on every page;
91- share a cookie domain if you ever set one wider than a host.
92
93Use a separate registrable domain for sites when the repositories publishing them
94are not all trusted: `pages.example.net` for a forge at `forge.example.com`. The
95two then cannot be same-site. If the sites are as trusted as the forge itself, a
96subdomain is fine and keeps certificate management to one domain.
97