8 ms·
A tiny Docker image to serve static websites
- zahllos 4y agoThe only thing I would change: I would use Caddy and not thttpd. This way the actual binary doing the serving is memory-safe. It may well require more disk space, but it is a worthwhile tradeoff I think. You can also serve over TLS this way.
- tadbit 4y agoI love stuff like this. People will remark about how this is a waste of time, others will say it is absolutely necessary, even more will laud it just for the fun of doing it. I'm in the middle camp. I wish software/systems engineers would spend more time optomising for size and performance.
- encryptluks2 4y agoThe difference between a systems engineer and a software engineer is that to a systems engineer a half functioning 5MB docker image is okay but to a software engineer a fully functional 5GB Node image is fine.
- ttty 4y agoPremature optimisation? 5 gb doesn’t matter. It’s not great, don’t get me wrong.
- deleted 4y ago[deleted]
- qbasic_forever 4y agoI think the real value is just focusing on the absolute minimum necessary software in a production docker/container image. It's a good practice for security with less surface area for attackers to target.
- memish 4y agoWouldn't removing Docker entirely be a good optimization?
- kube-system 4y agoDocker adds other value to the lifecycle of your deployment. An "optimization" where you're removing value is just a compromise. Otherwise we'd all run our static sites on UEFI.
- jamal-kumar 4y agoyeah see some of us still do this on OSes that haven't turned into a giant bloated hodgepodge of security theatre and false panacea software. docker has dead whale on the beach vibes. what value does it offer to those of us who have moved on from the mess linux is becoming?
- themacguffinman 4y agoOut of curiosity, what OS have you moved on to?
- jamal-kumar 4y agoOpenBSD for the past 10 years or so has been really good to me and my clients, and it just keeps on getting better while linux keeps on getting worse. It's kind of a nobrainer these days. Hell if you just need to serve static HTTP it even has its own built in webserver now: https://man.openbsd.org/httpd https://man.openbsd.org/httpd
- kube-system 4y agoI’m not suggesting it has value to everyone. I’m suggesting it has value to the people who see value in it.
- jamal-kumar 4y ago
- kissgyorgy 4y agoRedbean is just 155Kb without the need for alpine or any other dependency. You just copy the Redbean binary and your static assets, no complicated build steps and hundred MB download necessary. Check it out: https://github.com/kissgyorgy/redbean-docker https://github.com/kissgyorgy/redbean-docker
- mrweasel 4y agoThere's also the 6kB container, which uses asmttpd, a webserver written in assembler. https://devopsdirective.com/posts/2021/04/tiny-container-image/ https://devopsdirective.com/posts/2021/04/tiny-container-ima...
- tyingq 4y agoAnd it does https/tls, where thttpd does not.
- somenewaccount1 4y agoI'm confused how the author considers thttpd more 'battle tested' if it doesn't resolve https. Either way though, it's a great article I'm glad the author took to write. His docker practices are wonderful, wish more engineers would use them.
- cassandratt 4y ago"Battle tested" typically means that the code has been running for a long time, bugs found, bugs squashed, and a stability has been attained for a long time. It's usage predates the "information wars", back when we really didn't think about security that much because nothing was connected to anything else that went outside the companies, so there were no hackers or security battles back then. So I suspect this is the authors frame of reference.
- SahAssar 4y agoThe term 'battle tested' has nothing to do with amount of features, it's about how proven the stability and/or security of the included features included are. The term also usually carries a heavy weight towards older systems that have been used in production for a long time since those have had more time to weather bugs that are only caught in real-world use.
- 0xbadcafebee 4y agoIf you use "-Os" instead of "-O2", you save 8kB! However, Busybox also comes with an httpd... it may be 8.8x bigger, but you also get that entire assortment of apps to let you troubleshoot, run commands in an entrypoint, run commands from the httpd/cgi, etc. I wouldn't run it in production.... but it does work :)
- cutler 4y agoIs nothing sacred? The KuberDocker juggernaut leaves no stone unturned. Laughable given that Docker was originally designed for managing massive fleets of servers at FAANG-scale.
- jandeboevrie 4y agoBut why would you prefer Docker like this over, for example, running thttpd directly? Saves you a lot of Ram an indirection?
- qbasic_forever 4y agoRun this on a linux host and it isn't that much different from running thttpd directly. There's just some extra chroot, cgroups, etc. setup done before launching the process but none of that gets in the way once it's running. Docker adds a bit of networking complexity and isolation, but even that is easily disabled with a host network CLI flag. It's really only on windows/mac where docker has significant memory overhead, and that's just because it has to run a little VM with a linux kernel. You'd have the same issue if you tried to run thttpd there too and couldn't find a native mac/windows binary.
- ttty 4y agoI don’t want to touch the root of my server. I rather add a new container that doesn’t modify anything on the root. Benefits: can cleanly and delete 100% of what was installed. If you use something on root can always infect, save cache, logs… I don’t want to impact anything else running on my server. I don’t want anything to depend on that either silently. Docker is the best thing. I just can’t understand how people still can’t get the benefits yet. Is Amazing to start a project you had 3 years ago and just works and you can deploy without reading any docs. Just spin a docker container. Eat, safe and just works.
- somenewaccount1 4y agoFor one, because his home server provides multiple utilities, not just this one project, and without docker he starts to have dependency conflicts. He also like to upgrade that server close to edge, and if that goes south, he want to rebuild and bring his static site up quickly, along with his other projects.
- Yeroc 4y agoWell in the article he ended up compiling thttpd statically so he wouldn't have dependency conflicts if he ran it directly. Funny how there's overlap in docker solutions that solve different but related issues for non-docker deploys as well...
- nitinagg 4y agoFor static websites, hosting them directly on S3 with cloudfront, or on cloudflare might be a better option?
- flatiron 4y agoHow’s the free tier on aws for s3 and cloudfront? I can think of free alternatives that are equally as good if not better.
- hedora 4y agoS3 + cloudfront + lambda is costing me pennies per month for a trivial site. What are the free alternatives that beat it? Requirements: - rsync style publishing - not supported by tracking users. - raw static file hosting (including html) - redirect foo.com/bar to foo.com/bar/index.html (this is why I need lambda...) - zero admin https certificate management
- flatiron 4y agoGitHub pages gives you all this except the redirect and replace rclone with…git and is free (although evil Microsoft blah blah)
- MuffinFlavored 4y agoor https://pages.github.com/ https://pages.github.com/ maybe?
- calltrak 4y ago
- mg 4y agoFor static websites, is there any reason not to host them on GitHub? Since GitHub Pages lets you attach a custom domain, it seems like the perfect choice. I would expect their CDN to be pretty awesome. And updating the website with a simple git push seems convenient.
- coding123 4y agoWell, not everything is open source.
- tekromancr 4y agoCan you do SSL?
- dewey 4y agoYes, since 2018.
- qbasic_forever 4y agoI don't think you can set a page or URL on github to return a 301 moved permanently response or similar 3xx codes. This can really mess up your SEO if you have a popular page and try to move off github, you'll basically lose all the clout on the URL and have to start fresh. It might not matter for stuff you're just tossing out there but is definitely something to consider if you're putting a blog, public facing site, etc. there.
- nobodywasishere 4y agoI have a few 301 redirects setup on github pages $ curl https://nobodywasishere.github.io # moved to https://blog.eowyn.net <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx</center> </body> </html> $ curl https://blog.eowyn.net/vhdlref-jtd # moved to https://blog.eowyn.net/vhdlref <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx</center> </body> </html>
- 0xb0565e487 4y agoI don't know why there is a big fish at the top of your website, but I like it a lot.
- bachmitre 4y agoHow many requests can thttpd handle simultaneously, compared to, say nginx ? It's a moo point being small if you then have to instantiate multiple containers behind a load balancer to handle simultaneous requests.
- timcavel 4y ago
- mr-karan 4y agoWhile this is remarkably a good hack and I did learn quite a bit after reading the post, I'm simply curious about the motivation behind it? A docker image even if it's a few MBs with Caddy/NGINX should ideally be just pulled once on the host and sit there cached. Assuming this is OP's personal server and there's not much churn, this image could be in the cache forever until the new tag is pushed/pulled. So, from a "hack" perspective, I totally get it, but from a bit more pragmatic POV, I'm not quite sure.
- marginalia_nu 4y agoThe less resources you use from your system, the more things you can do with your system.
- spicybright 4y agoOnly matters if you're actually using those extra cycles or not. The majority of web servers hover at <10% CPU just waiting for connections.
- munk-a 4y agoI don't know if that's really true - if you're renting the server from a cloud provider chances are you can bump down the instance size if you don't need the extra processing capacity... and if it's a server you manually maintain I think lighter usage generally decreases part attrition, though the other factors in that are quite complex.
- throwaway894345 4y agoIt gets pulled once per host, but with autoscaling hosts come and go pretty frequently. It's a really nice property to be able to scale quickly with load, and small images tend to help with this in a variety of ways (pulling but also instantiating the container). Most sites won't need to scale like this; however, because one or two hosts is almost always sufficient for all traffic the site will ever receive.
- 4y ago
- KronisLV 4y ago> My first attempt uses the small alpine image, which already packages thttpd: # Install thttpd RUN apk add thttpd Wouldn't you want to use the --no-cache option with apk, e.g.: RUN apk add --no-cache thttpd It seems to slightly help with the container size: REPOSITORY TAG IMAGE ID CREATED SIZE thttpd-nocache latest 4a5a1877de5d 7 seconds ago 5.79MB thttpd-regular latest 655febf218ff 41 seconds ago 7.78MB It's a bit like cleaning up after yourself with apt based container builds as well, for example (although this might not always be necessary): # Apache web server RUN apt-get update && apt-get install -y apache2 libapache2-mod-security2 && apt-get clean && rm -rf /var/lib/apt/lists /var/cache/apt/archives But hey, that's an interesting goal to pursue! Even though personally i just gave up on Alpine and similar slim solutions and decided to just base all my containers on Ubuntu instead: https://blog.kronis.dev/articles/using-ubuntu-as-the-base-for-all-of-my-containers https://blog.kronis.dev/articles/using-ubuntu-as-the-base-fo...
- wereHamster 4y agoI used this as a base image for a static site, but then needed to return a custom status code, and decided to build a simple static file server with go. It's less than 30 lines, and image size is <5MB. Not as small as thttpd but more flexible.
- uoaei 4y agoNail, meet hammer.
- souenzzo 4y agoIs it smaller than darkhttpd? https://unix4lyfe.org/darkhttpd/ https://unix4lyfe.org/darkhttpd/
- kristianpaul 4y agoWhy do we need this when you can run a web server inside systemd?
- hedora 4y agoThis doesn't hijack a bunch of stuff on the host OS and replace it with garbage versions. I want things like DNS, X11 screeb locking, ssh session management, syslog, etc. to just work. I can't figure out how to fix any of that stuff under systemd, and at least one is always broken by default in my experience.
- amanzi 4y agoI assume the author would then publish this behind a reverse proxy that implements TLS? Seems like an unnecessary dependency, given that Docker is perfect for solving dependency issues.
- EnigmaCurry 4y agoThat's certainly what I would do. I think its great that thttpd does not include a TLS dependency itself. Every once in awhile I find a project that forces their own TLS and its annoying to undo it.
- pojzon 4y agoTbh the moment the author thought about hosting yourself anything to serve static pages -> it was already too much effort. There are free ways to host static pages and extremely inexpensive ways to host static pages that are visited mullions of times per month using simply services built for that.
- riffic 4y agothere are services specifically for static site hosting. I'd let them do the gritty devops work personally. Netlify, Amplify, Cloudflare Pages, etc.
- nilsandrey 4y agoI use them too. Sometimes I like to have some repos with the static content, which get deployed by a CD tool to those services. It's common for me when debugging or testing locally in my PC or LAN, to include some docker build for those repos which I don't use at production time, but I used it locally. Maybe is not a big problem at all, but I use it that way, specially when in my projects the CND used is not a free one. Makes sense?
- riffic 4y agojust working off the headline. visiting your link does a great job explaining the use case you have. I'll revisit tonight for a closer look.
- krnlpnc 4y agoUp next: how to serve a LAMP site from a single docker image
- hedora 4y agoIt's pretty easy. I put the data in a bind mount on btrfs on my synology NAS. It snapshots the FS and does an incremental backup with hyper backup each night. The backup is crash coherent, zero downtime, and the RDBMS doesn't need to know about it. This is really useful for tiny little services that each want a different database server.
- superkuh 4y agoWell, this will definitely serve an unchanging static website. But unchanging static websites are just archives. Most static websites have new .html and other files added on whim regularly.
- EnigmaCurry 4y agoYou can just mount an external volume on top of /home/static to and be able to change the files that way. But for a single-page-app I think it works great to be able to version the entire site in the docker image tag.
- kra34 4y agoI love it! Can you add SSL though? Does it support gzip compression? What about Brotli? I like that it's small and fast so in addition to serving static files can it act as a reverse proxy? What about configuration? I'd like to be able to server multiple folders instead of just one? Where can I submit a feature request ticket?
- stevefan1999 4y agohttps://github.com/weihanglo/sfz https://github.com/weihanglo/sfz check this out
- CameronNemo 4y agoThis seems to be intended for local host usage exclusively. Is anyone using this for public or even internal http hosting?
- nilsandrey 4y agoI think is not precisely an active project, but it's open on GitHub[1], I guess we can try to open issues there. - [1] https://github.com/lipanski/docker-static-website https://github.com/lipanski/docker-static-website
- CameronNemo 4y agoI do something similar at work for internal only static docs. The image is a small container with an http daemon. It gets deployed as a statefulset and I mount a volume into the pod to store the static pages (they don't get put into the image). Then I use cert-manager and an Istio ingress gateway to add TLS on top. Updating the sites (yes, several at the same domain) is done via kubectl cp, which is not the most secure but good enough for our team. I could probably use an rsync or ssh daemon to lock it down further, but I have not tried that.
- mro_name 4y agoDocker, really? Sounds like brain surgery in order to make a jam sandwich to me.
- Casteil 4y agoIt's a good way to compartmentalize if you've got a lot going on on a single machine.
- mro_name 4y ago> compartmentalize a static website, srsly?
- Casteil 4y agoUh, yeah? Could host dozens (or even hundreds) of different sites/domains with different degrees of functionality in different languages/frameworks for different clients on one machine.
- mro_name 4y ago> have millions of files Congratulations. I have millions of files on my static sites. So what? Would you recommend a container for each? To what purpose? > different degrees of functionality We're still talking static sites. There is no 'functionality', right?
- Casteil 4y ago> Congratulations. I have millions of files on my static sites. So what? Would you recommend a container for each? To what purpose? ...what? Where are you quoting that from? No, I'm not recommending Docker if all you do is host static pages. > We're still talking static sites. No, I said "if you've got a lot going on on a single machine" - I didn't just mean static sites. I did respond with "different sites/domains with different degrees of functionality in different languages/frameworks", which means a variety of services, e.g. one client may be a static page, another might use a backend/API in Node, and another in C#/.NET - etc.. heck, you might even used containerized DBs for some of them. Hence Docker.
- sgtnoodle 4y agoSeems pretty silly. That being said, I did the exact same thing a couple years ago for work. My first attempt was to use busybox's built-in httpd, but it didn't support restarts. I vaguely recall settling on the same alpine + thttpd solution. The files being served were large, so the alpine solution was good enough.
- rhim 4y agoalthttpd beats this: https://hub.docker.com/r/rouhim/althttpd/tags https://hub.docker.com/r/rouhim/althttpd/tags (~63 KB)
- patrakov 4y agoThat's a good educational resource to show to people who need to learn about multi-stage Docker builds.