tunnelbana

Crates.iotunnelbana
lib.rstunnelbana
version0.2.0
created_at2024-11-11 23:48:41.445805+00
updated_at2025-06-05 16:36:27.35472+00
descriptionServe static websites with ease and speed.
homepage
repositoryhttps://github.com/randomairborne/tunnelbana
max_upload_size
id1444334
size47,803
valkyrie_pilot (randomairborne)

documentation

README

Tunnelbana

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.

Why?

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.

How do I use it?

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.

Docker

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"]

Configuration

Headers

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

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}

I like one of these features, and I want it in my app

You're in luck! Almost everything in Tunnelbana is a seperated crate- all the main executable does is glue them together.

Commit count: 113

cargo fmt