Coming out of some discussion on Discord with @gregsadetsky, I thought I'd pull together the different requests for routing and rewriting options, as well as some prior art in other projects. Hopefully this might help in coming up with an approach that disco can use for taking this forward.
Problem statement
As a user, I'm able to create static sites and let disco manage hosting them (via Caddy, although this is an internal detail).
However, this is limited to basic folder-based routing:
example.com/ -> ./index.html
example.com/foo/ -> ./foo/index.html
example.com/foo is automatically redirected to example.com/foo/ and then interpreted as above.
Additionally, any paths not found in the folder structure return an empty 404 code.
As a user, I might want to configure this behaviour, in a way that's slightly more complex - custom 404 pages, extensions, headers etc.
One option (as a user) is to bundle the output files in a docker image with a web server and run it as a normal service (common approaches are to use caddy, nginx, etc.), and this is a common solution in other deployment models such as Kubernetes. However, it's a really nice feature to be able to host multiple static sites on a single disco host without each one taking up resources for their individual web servers. There's no technical limitation preventing disco from configuring caddy with extra settings - the question is what options could/should be exposed and in what format.
General idea
For projects with type: static or type: generator, allow config options in the repo which configure Caddy behaviour beyond the default config.
As always, the devil is in the details:
- What file contains this data?
disco.json or a separate file
- API format?
- Drop-in caddy config, or custom DSL?
- Instinct leans towards a DSL, which can be validated and injected without impacting other services
- If a DSL, what options should be allowed and in what format?
Concrete examples of useful features
Some previous issues raised that might fall under this umbrella:
Possibly of interest, some common pattern identified by Caddy at https://caddyserver.com/docs/caddyfile/patterns:
- Redirect
www. subdomain (www.example.com -> example.com)
- Rewrite requests to add/remove trailing slashes
- Single-page apps (all paths served with the same
index.html)
Prior art
From a brief search - I'm sure more examples could be added.
_redirects file
Supported by netlify, Cloudflare, Gitlab
Seems to be a common standard? Web _redirects File Specification
The format is fairly simple - each line contains 2 or 3 entries: from to [status].
This also captures domain-level redirects.
In some implementations it seems to cover rewrites as well, if the status code is set to 200. In this case an entry of /* / 200 would cover the SPA usecase.
'Splat' and wildcard handling would need to be parsed and converted to Caddy format.
CSV or JSON redirects
Examples at Vercel.
By having entries as more complex objects, this can handle additional features, such as caseSensitive or preserveQueryParams.
404 files
Github pages automatically spots a 404.html in the serve root, and returns it alongside any 404 return codes.
Vercel allows setting a custom 404 path among its redirects - this approach is also metnioned in the IPFS spec for _redirects above.
Coming out of some discussion on Discord with @gregsadetsky, I thought I'd pull together the different requests for routing and rewriting options, as well as some prior art in other projects. Hopefully this might help in coming up with an approach that disco can use for taking this forward.
Problem statement
As a user, I'm able to create static sites and let disco manage hosting them (via Caddy, although this is an internal detail).
However, this is limited to basic folder-based routing:
example.com/->./index.htmlexample.com/foo/->./foo/index.htmlexample.com/foois automatically redirected toexample.com/foo/and then interpreted as above.Additionally, any paths not found in the folder structure return an empty 404 code.
As a user, I might want to configure this behaviour, in a way that's slightly more complex - custom 404 pages, extensions, headers etc.
One option (as a user) is to bundle the output files in a docker image with a web server and run it as a normal service (common approaches are to use caddy, nginx, etc.), and this is a common solution in other deployment models such as Kubernetes. However, it's a really nice feature to be able to host multiple static sites on a single disco host without each one taking up resources for their individual web servers. There's no technical limitation preventing disco from configuring caddy with extra settings - the question is what options could/should be exposed and in what format.
General idea
For projects with
type: staticortype: generator, allow config options in the repo which configure Caddy behaviour beyond the default config.As always, the devil is in the details:
disco.jsonor a separate fileConcrete examples of useful features
Some previous issues raised that might fall under this umbrella:
.htmas directory index add index.htm as index file for static sites #90404.htmlif available Sugg: serve custom 404 if present when site type is generator #8Possibly of interest, some common pattern identified by Caddy at https://caddyserver.com/docs/caddyfile/patterns:
www.subdomain (www.example.com->example.com)index.html)Prior art
From a brief search - I'm sure more examples could be added.
_redirectsfileSupported by netlify, Cloudflare, Gitlab
Seems to be a common standard? Web _redirects File Specification
The format is fairly simple - each line contains 2 or 3 entries:
from to [status].This also captures domain-level redirects.
In some implementations it seems to cover rewrites as well, if the status code is set to 200. In this case an entry of
/* / 200would cover the SPA usecase.'Splat' and wildcard handling would need to be parsed and converted to Caddy format.
CSV or JSON redirects
Examples at Vercel.
By having entries as more complex objects, this can handle additional features, such as
caseSensitiveorpreserveQueryParams.404 files
Github pages automatically spots a
404.htmlin the serve root, and returns it alongside any 404 return codes.Vercel allows setting a custom 404 path among its redirects - this approach is also metnioned in the IPFS spec for
_redirectsabove.