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.

Blame · docs/sites.md

Line attribution on main · 96 line(s)

520470e1
Keenan Nemetz
16d ago
1 # Sites
2
3 A website can be a branch. That keeps publishing simple and keeps the files with
ab326d3a
Keenan Nemetz
14d ago
4 the repository. Vole serves a repository's `pages` branch at `<repo>.<pages_domain>`.
520470e1
Keenan Nemetz
16d ago
5 There is no build step on the server: change the branch and the next request sees
6 the new files.
7
8 ## Publish a build directory
9
10 Most websites are generated into a directory such as `dist/`. Vole can publish
11 that directory as a snapshot, so the branch contains exactly those files. If you
12 delete a page from the build, it stops being served.
13
14 ```sh
15 npm run build
16 vole pages deploy dist # publish dist/ to the pages branch
17 vole pages deploy dist --dry-run # show changes without pushing
18 vole pages status # show the current branch and files
19 vole pages unpublish # take the site down
20 ```
21
22 Publishing the same files twice does nothing. Use `--branch` if the instance
23 serves a different branch than `pages`.
24
25 Dotfiles such as `.nojekyll` and `.well-known/` are published. Vole skips `.git`
26 and symbolic links. A site is just files, and a link pointing outside the build
27 directory would publish something you did not choose.
28
29 ## Publish by hand
30
31 Plain Git is enough:
32
33 ```sh
34 git switch --orphan pages
35 printf '<h1>hello</h1>\n' > index.html
36 git add index.html
37 git commit -m "site"
38 git push origin pages # live at https://demo.pages.example.com/
39 ```
40
41 ## Turn sites on
42
43 ```toml
44 pages_domain = "pages.example.com" # <repo>.pages.example.com
45 pages_ref = "pages" # branch to serve
46 pages_procs = 4 # Git reader processes per active site
47 pages_cache_bytes = 33554432 # 32 MiB of cached files
48 ```
49
50 Set `pages_domain` to enable websites. If you change `pages_ref`, pass the same
51 branch 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
816cc543
Keenan Nemetz
11d ago
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.
520470e1
Keenan Nemetz
16d ago
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
642e5994
Keenan Nemetz
14d ago
66 With automatic HTTPS enabled (`https_addr`), Vole obtains a certificate for each
67 site host the first time it is requested, as long as the repository exists and is
68 publicly readable. A wildcard DNS record pointing at the instance is enough;
69 wildcard certificates are not supported, so each host is issued separately. Without `https_addr`, terminate
70 TLS in a proxy in front of `http_addr` and keep the `Host` header: it is how Vole
71 knows which site was requested. See
72 [Configuration § Automatic HTTPS with ACME](configuration.md#automatic-https-with-acme)
73 and [Configuration § Running behind a proxy](configuration.md#running-behind-a-proxy).
520470e1
Keenan Nemetz
16d ago
74
75 A workflow can publish the site as its last step. See
70b70264
Keenan Nemetz
15d ago
76 [Workflows § Publish a website](workflows.md#publish-a-website).
701232cf
Keenan Nemetz
12d ago
77
78 ## Same-site risk
79
80 A 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`
82 and `*.pages.example.com`, say — then every site is *same-site* with the forge,
83 and 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
93 Use a separate registrable domain for sites when the repositories publishing them
94 are not all trusted: `pages.example.net` for a forge at `forge.example.com`. The
95 two then cannot be same-site. If the sites are as trusted as the forge itself, a
96 subdomain is fine and keeps certificate management to one domain.