static-server: an HTTP server in Go for static content
eli.thegreenplace.net
eli.thegreenplace.net
I say publish your work. Chances are, no one will care and you have a nice backup of your code. And if someone does find it useful, then great!
go run github.com/eliben/static-server@latest
I had to upgrade to Go 1.21 for this to work - I was previously on Go 1.20. "brew upgrade go" worked for me.Looks like almost the entire implementation is here, it's mostly CLI option parsing logic: https://github.com/eliben/static-server/blob/main/internal/s...
fileHandler := serveLogger(serveLog, http.FileServer(http.Dir(rootDir))) $ go run .
go: errors parsing go.mod:
.../static-server/go.mod:3: invalid go version '1.21.0': must match format 1.23
Eli, you might consider changing that to "go 1.20" so it works on Go 1.20 (and older, actually -- it's the 1.2.3 format that is getting in the way on Go pre-1.21).https://github.com/philippgille/serve
One difference is that it can create a TLS cert for you, instead of having to supply one via CLI arg.
I don't recommend using it in its current form though due to its (the compiled binaries') Go version being outdated.
[1]: https://github.com/eliben/static-server/blob/main/internal/s...
$ caddy file-server
It does templates, TLS, and other production things really easily from the command line too, including automatically getting certificates: $ caddy file-server --domain example.com
Done!I think projects like static-server are wonderful learning examples of how to get Useful Things done in Go.
I assume that's just poorly phrased?
But for the `caddy respond` command, minimal templates are available by default; see the docs here: https://caddyserver.com/docs/command-line#examples
Its syntax for being configured as a reverse proxy (secure front-end to less secure back-end servers) is similarly pretty easy.
I haven't looked at it in a long time because I recall them screwing with their terms of service so it wasn't fully FOSS by the most liberal definition.
Caddy's ease of use is one feature, but there are many more - like the ability to massively scale your TLS to thousands of sites reliably. And to use the on-line configuration API to make changes to your server. There's a ton to discover with Caddy, it's not just a tool for beginners. ;)
This is great for if you want to be able to do zero-downtime deploys of new applications behind a proxy server or similar.
(One reason we don't use signals in Caddy 2. So uncivilized.)
Caddy 2 was created when I got serious about it, and we had governments and enterprises starting to rely on the project.
Now we exist because we advocate for (and deliver!) HTTPS on every site, memory safety, dynamic configuration, extensibility, and many more features valuable in a modern web server.
Hope that helps :)
>I needed a quick and easy web server
I am trying to reason with what I know, but wouldn't something like "python -m http.server 9000" suffice? Or nginx? These are battle tested and python is there on most platforms.
Or is there more depth to this specific web server that others don't have?
And Caddy is very well battle-tested too, btw. ;)
It seems like in every thread about web servers, the developers are in here peddling their wares, and the disciples pour in with endless praise.
It's another product with insane footgun defaults (the admin API on localhost) in a sea of mature alternatives. That's all I need to know.
I don't mean to insult anyone's hard work but in the words of Josh Baskin, "I don't get it."
The simplest cmdline I found to run it as a local server on a non-priveledged port with listings is:
$ caddy file-server --listen localhost:8099 --browse
Is there a simpler way I'm missing?The --browse flag is optional and unrelated to ports/privileges. Otherwise, that sounds about right. Caddy defaults to port 80 unless you give it a domain name, then it defaults to port 443 and redirects HTTP on port 80 to HTTPS.
And a special call-out to your dedication to providing amazing documentation. Caddy is what all projects should aspire to be.
Anyway I decided to try Caddy to quickly get up and running and had a good setup in minutes including certificates for multiple domains. Even added wildcard certificates which I never figured out with Lets Encrypt, just because I could.
Thanks for this amazing software :-)
I know I can write it in JSON, but IMO the greatest appeal of Caddy is its simple and easy-to-read Caddyfile!
This is something I could prioritize if a business wanted to sponsor this; but right now the most pressing things are updating the docs, revamping our test suite, and I have a few action items for existing sponsors I need to prioritize too.
Anyway, no timeline -- but definitely something wanted!
PS. There is kind of Caddyfile support here: https://github.com/RussellLuo/caddy-ext/tree/master/layer4
But yes, in general: Caddy's one-liner is a safe way to serve static files in the sense that remote services can't upload files or escape memory bounds to run arbitrary code. It encrypts your connections for you, so they're basically safe from surveillance and modification.
The elements you're describing are all external factors that have nothing to do with serving static files specifically. For example, a reverse proxy just multiplexes requests coming in on a port to various backends, maybe making modifications along the way. Authentication will restrict access to only allowed users, if that's something you require. Containers are more a way of administering a system or mitigating very specific risks that have niche relevance with static Go programs; and VLANs are just ways of isolating network traffic, but again it's somewhat orthogonal to file serving.
Overall, `caddy file-server` is better than Python's simple HTTP server in every way, though: static binary, faster performing, production-ready (handles Range requests properly, and a few other details), automatic HTTPS, folder indices, etc...
[0] https://github.com/eliben/static-server/blob/3ce83524ed54298...
$ npm install http-server
$ http-server .
$ go run github.com/eliben/static-server@latest
I have this seen also in automotive. "This is no problem, because this is not connected to the Internet." Then a few years later you have a DefCon presentation "GM hack, you can control the whole car via the Internet".
The shutdown endpoint is used for robust testing; I suppose I can hide it a bit more, like using an environment variable or something.
Mainly because of the shutdown endpoint, but also that the -cors flag returns "Access-Control-Allow-Origin: *" exposing you to arbitrary cross origin requests.
While true, I don't think the author should refrain from making code available based on the potential negatives from others using code they didn't even bother to read the documentation for.
Need I be called out, now?