Tunnelbana is a collection of crates designed to make fast Rust static file servers with tower. It's named for the swedish word for subway.
Tunnelbana was created to reduce my dependence on Cloudflare. I love Cloudflare and their services, but I don't love the direction they're going with the pages product, so I thought I'd make my own thing.
Tunnelbana is available on crates.io, where it can be easily
used as a binary with tunnelbana /var/www/html
after a cargo install tunnelbana
.
It is also available on ghcr,
where it can be used with bind mounts or as a build source for a container as demonstrated below.
FROM node:alpine AS builder
# You could also build your app any other way, as long as it outputs a directory that can be copied
# to some path in a container.
COPY ./xpd-web/ /build
WORKDIR /build/
RUN npm install
RUN npm run build
# asset squisher is a seperate project, made by the same author. It works well with tower-http
# precompression, which tunnelbana uses.
FROM ghcr.io/randomairborne/asset-squisher:latest AS compressor
COPY --from=builder /build/dist/ /build/dist/
RUN asset-squisher --no-compress-images /build/dist/ /build/compressed/
FROM ghcr.io/randomairborne/tunnelbana:latest
COPY --from=compressor /build/compressed/ /var/www/html/
CMD ["tunnelbana", "/var/www/html"]
Headers can be customized with the /_headers
file in the root of the directory.
Headers syntax is an unindented target path, followed by a list of indented key: value
pairs.
You can use {named_captures}
in the target path, and at the end you can use {*wildcards}
.
Limitations:
- It is not possible to have a wildcard affect pages with more specific headers. Create an issue if you need this.
/my/cool/header
X-Cool-Header: radical
/{lol}/header_path
X-Lol: very funny.
/{*everything}
X-On-Every-Page: on_every_page
Redirects can be customized with the /_redirects
file in the root of the directory.
Redirect syntax is very simple. There are three space-seperated columns on each line of text:
the path where the redirect will apply, the target (with interpolations), and an optional status code.
You can use the same {capturing_item}
and {*wildcards}
at the ends
as in the headers, and they can even be used in the target with {capturing_name}
.
Limitations:
- You cannot have a wildcard with a suffix, it must be a suffix for the redirect.
/boring https://example.org 302
/{capture}/ /en/{capture}/
/en/{*splat} /{splat}
You're in luck! Almost everything in Tunnelbana is a seperated crate- all the main executable does is glue them together.
- tunnelbana-etags is an ETag generation system that works closely with
ServeDir
- tunnelbana-headers adds headers to routes, and can parse
_headers
files. - tunnelbana-hidepaths is a simple layer which can respond with 404s to specific paths.
- tunnelbana-redirects turns routes into redirects, and can parse
_redirects
files.