I’m currently researching the best method for running a static website from Docker.
The site consists of one single HTML file, a bunch of CSS files, and a few JS files. On server-side nothing needs to be preprocessed. The website uses JS to request some JSON files, though. Handling of the files is doing via client-side JS, the server only need to - serve the files.
The website is intended to be used as selfhosted web application and is quite niche so there won’t be much load and not many concurrent users.
I boiled it down to the following options:
- BusyBox in a selfmade Docker container, manually running
httpd
or The smallest Docker image … php:latest
(ignoring the fact, that the built-in webserver is meant for development and not for production)- Nginx serving the files (but this)
For all of the variants I found information online. From the options I found I actually prefer the BusyBox route because it seems the cleanest with the least amount of overhead (I just need to serve the files, the rest is done on the client).
Do you have any other ideas? How do you host static content?
I just use nginx in docker. It runs from a Pi4 so needs to be lightweight. I’m sure there are lighter httpd servers to use, but it works for me. I also run nginx proxy manager to create a reverse proxy and to manage the certificate renewal that comes from Let’s Encrypt.
Same here. I have a few static sites setup to just be served via nginx.
Third for nginx here
I have a few static sites that are just nginx containers, one is just simple links to other things I run, to make it easy for my wife and some friends. Easy, lightweight, unprivileged - my favorite combo.
The answer is get a minimum linux image, add nginx or apache, and put your content on the relevant place. (Basically, your third option.)
Do not bother about the future of nginx. Changing the web server on that image is the easiest thing in the world.
I personally package the files in a scratch or distroless image and use https://github.com/static-web-server/static-web-server, which is a rust server, quite tiny. This is very similar to nginx or httpd, but the static nature of the binary removes clutter, reduces attack surface (because you can use smaller images) and reduces the size of the image.
Thanks, this looks actually pretty great. From the description it’s basically BusyBox httpd but with Nginx stability and production-readiness and functionality. It also seems to be actively developed.
caddy can serve the files and deal with SSL certificates in case you put this in a public domain.
Caddy is the way to go.
My setup already has Nginx Proxy Manager to handle SSL. This is specifically about serving files from within a docker container with as little overhead as possible.
I see from your other comments that you’re already running nginx in other containers. The simplest solution would be to make use of one of them. Zero overhead since you’re not adding any new container. 🙂
You mentioned you’re using NPM, well NPM already has a built-in nginx host that you can reach by making a proxy host pointed at http://127.0.0.1:80 and adding the following to the “Advanced” tab:
location / { root /data/nginx/local_static; index index.html; }
Replace the root location with whatever dir you want, use a volume option on the NPM container to map the dir to the host, put your files in there and that’s it.
Acronyms, initialisms, abbreviations, contractions, and other phrases which expand to something larger, that I’ve seen in this thread:
Fewer Letters More Letters Git Popular version control system, primarily for code HTTP Hypertext Transfer Protocol, the Web SSL Secure Sockets Layer, for transparent encryption nginx Popular HTTP server
4 acronyms in this thread; the most compressed thread commented on today has 14 acronyms.
[Thread #575 for this sub, first seen 5th Mar 2024, 14:15] [FAQ] [Full list] [Contact] [Source code]
Ngl calling nginx a contraction of “popular https server” is kinda wild
If your looking for a small size you could build a custom image with buildroot and lighttpd. It is way, way overkill but it would be the smallest.
For something easier use the latest image of your web server of choice and then pass though a directory with the files. From there you can automate patching with watch tower.
First thing you mention is such a fun and useful exercise. But as you point out, way overkill. Might even be dangerous to expose it. I got mine to 20kb on top of busybox.
There is something that tickles the right spots when a complete container image significantly smaller than the average js payload in “modern” websites.
I’ve read that you’re trying for minimal resource overhead.
Is lighttpd still a thing? Back in the day I used it to deliver very simple static Http pages with minimal resource usage.
I found a docker image with like 4 mb size but being two years old I don’t know how well maintained lighttpd is these days.
The old age of the Docker image is a bit of a red flag to me.
I settled with SWS since the Docker image and a locally installable version are actively maintained by the creator. It just serves static files and optionally directory listing as JSON (which comes in quite handy).
Forget about docker. Run caddy or some similar webserver that is a single file next to the assets to serve.
Containers are a perfectly suitable use-case for serving static sites. You get isolation and versioning at the absolutely negligible cost of duplicating a binary (the webserver - which in case of the one I linked in my comment, it’s 5MB of space). Also, you get autostart of the server if you use compose, which is equivalent to what you would do with a Systemd unit, I suppose.
You can then use a reverse-proxy to simply route to the different containers.
Why? It seems like docker is way more flexible and maintainable.
I already have a fully set up docker environment that serves all sorts of things (including some containers that serve special static content using Nginx).