In my last post about redesigning the Awyr site, I mentioned using rwasa to serve the content.
I found rwasa via an HN thread for one of their other projects, hnwatch. It was possibly a very canny bit of marketing, definitely appealing to the general userbase of HN.
2 Ton’s rwasa is a web server written in 64-bit assembly, and, to avoid simply regurgitating the content of 2 Ton’s page, I thought it might be worth looking at a number of aspects of the software that I appreciate:
- It’s a self-contained 364KB executable
- It has no configuration file
- It consumes about 2KB RAM while idle
Normally to serve content I’d go straight for nginx. It’s small, performant, well known, and well documented. It’s also capable of serving multiple sites from the same configuration file. However, to run nginx you either need to install it or compile it. rwasa scores here; if I want, I can quickly serve arbitrary content as my normal user. How often do you fire up a container or VM just to test some web content? With rwasa, I can just:
rwasa -foreground -bind 8080 -runas jonathon -sandbox /home/jonathon/documents/Awyr/www/_site/ -filestattime 1
and I have a small, local, web server. Yes,
jekyll serve does this too, but rwasa is far more responsive. It’s a
proper web server, after all. In case you’re wondering,
-filestattime sets the minimum amount of time rwasa
before it checks whether the file has changed (the default is 120 seconds; there are many other nice little performance
enhancements like this).
Notice that all of the information rwasa needs to serve the content is provided via command line arguments. The lack of a configuration file probably seems odd at first. What this means, though, is faster deployment. You can’t worry about misconfiguring something - instead, you point rwasa at your content, and that’s that.
Next up - memory footprint. For serving the above content, rwasa spawns two threads:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND jonathon 5950 0.0 0.0 1556 832 pts/3 S+ 21:11 0:00 rwasa -foreground -bind 8080 -runas jonathon -sandbox ... jonathon 5953 0.0 0.0 3300 1616 pts/3 S+ 21:11 0:00 rwasa -foreground -bind 8080 -runas jonathon -sandbox ...
which appear to reserve a total of 2448 bytes of RAM. I have yet to see how rwasa scales up to serving more than a handful of concurrent connections, but 2KB as a baseline? Can’t be bad.
Combined, these properties also make rwasa highly suited to containerisation. It’s a single process, with nearly zero configuration, so we don’t need supervisors or anything fancy. I use alpine as my Docker container base image (5MB!), so a Dockerfile could be as simple as:
FROM alpine:latest RUN apk -U -f upgrade && \ apk add wget ca-certificates && \ wget https://2ton.com.au/standalone_binaries/rwasa -O /usr/local/bin/rwasa && \ chmod a+x /usr/local/bin/rwasa VOLUME [ "/var/www", "/var/log/rwasa" ] EXPOSE 8000 CMD /usr/local/bin/rwasa -foreground -bind 8000 -sandbox /var/www -logpath /var/log/rwasa -errlog /var/log/rwasa/error.log
and if I could get
COPY to work it would be even simpler… However, this approach results in a 10MB
Docker image. It’s a little larger than an nginx equivalent of 7MB (which actually surprised me at first until I thought
of the extra overhead of wget and ca-certificates) but it’s worth it.
Written by Jonathon, categorised as software, 26 August 2015