Skip to content

Instantly share code, notes, and snippets.

@barelyhuman
Last active February 23, 2025 23:10
Show Gist options
  • Save barelyhuman/4cf3826abd228a5ac33b931a66e05c07 to your computer and use it in GitHub Desktop.
Save barelyhuman/4cf3826abd228a5ac33b931a66e05c07 to your computer and use it in GitHub Desktop.
Simple http2 server with caddy for static websites

Static File Server

Even though you should generally use a CDN for something like this, a very simple setup for smaller static websites on a VPS / VM is fine.

This gist comes with an example Caddyfile that can be used with caddy to serve any sub-folder in the /var/www path as a subdomain.

This reduces the overall effort required to create and register domains if you are going to keep it all on the same server.

The example Caddyfile shows how to set the flow up with the localhost domain but changing it to work with an actual domain should be rather simple and is documented as comments in the file.

*.localhost {
# basic error handling for cases where it doesn't find anything
handle_errors {
respond "{http.error.status_code} {http.error.status_text}" 404
}
root * /var/www/{labels.1}
# ↑ change to labels.2
# if you are using a subdomain like `blog.reaper.is` or labels.3
# if it's even more nested like `blog.internal.reaper.is`
# try using cleaner paths for `.html` files
@stripExtensions path_regexp strip (.*)\.(html)
redir @stripExtensions {re.strip.1} 301
# tie `/index` to `/index.html`
# done to make the url cleaner looking (purely aesthetic, can be removed
file_server {
index index.html
}
# part 2 of trying cleaner paths for `.html` files
# by checking if a .html exists for the requested path
try_files {path} {path}/ {path}.html
header {
Strict-Transport-Security max-age=31536000;
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy no-referrer-when-downgrade
X-XSS-Protection "1; mode=block"
}
# Basic compression and cache control
# we remove caching for .html and .css files as they change
# often when working with static assets
encode gzip zstd
header @stripExtensions Cache-Control "no-cache"
header {
Cache-Control "public, max-age=31536000"
-Cache-Control "*.html *.css"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment