8 ms·
Self-Contained Pure-Go Web Server with Lua, MD, HTTP/2, QUIC, Redis Support
- est31 8y agoThis is quite impressive, but this claim is a bit wrong: > All in one small self-contained executable. Size of algernon executable: 24.4 MiB Size of nginx-full executable: 1.1 MiB Size of apache2 executable: 648K
- mholt 8y agoIf that's the main criticism you have of the project, I'd say that's pretty good. In fact, the readme of this project is really thorough!
- est31 8y agoWell yeah it's definitely an interesting approach. I guess it's much more lean than running a whole Ubuntu container VM that has all of these things installed, or running a gigantic bloated Javascript toolchain just to convert the scss or md files to css or html.
- interfixus 8y agoVery civilized comment from mr. Caddy himself. Heartening, not least considering the kind of vendettas some projects - Caddy among them - have to put up with from competing developers.
- lawl 8y agoA big part is almost certainly the difference between dynamic and static linking. Can you run ldd on all of these and then report the combined size for each binary+libraries?
- est31 8y agoI don't have nginx installed (got the number from a web download of the .deb package), but running this for apache: $ echo $((`ldd /usr/sbin/apache2 | cut -d">" -f 2 | sed "s/(.*$//;s/ //" | xargs du -L | cut -f 1 | sed "s/$/+/" | xargs echo` 0)) 3200 So 3.2 MB of shared library dependencies. 1.8 MB just being the libc which is almost guaranteed to be used by a different program already.
- koffiezet 7y ago> 1.8 MB just being the libc which is almost guaranteed to be used by a different program already Not if we're talking about containers :)
- marcus_holmes 8y agoAs someone else commented, the huge size of Go executables is down to a design decision to include a map of functions for panic reporting. There was a whole discussion on this recently on HN. I don't know why the grandparent was downvoted. Go binaries are not small and the claim that this is a "small" single executable is untrue. Hopefully the Go team will give us a flag to decide for ourselves whether to optimise for executable size or initialisation time. I know I'm fed up of uploading 50Mb files over dodgy wifi+vpn connections to update my server. (edit fix repetition of design)
- throwaway5d097 8y agoThat's one thing that might motivate me to set up CI/CD on a server.
- baldomo 8y agoYou can actually pass LDFLAGS to any go tool (e.g. go build[1]). The flags are specified in the linker documentation[2] [1] https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies https://golang.org/cmd/go/#hdr-Compile_packages_and_dependen... [2] https://golang.org/cmd/link/ https://golang.org/cmd/link/
- marcus_holmes 8y agowhich is useful, except as far as I'm aware it doesn't cover this case. The original is at: https://science.raphael.poss.name/go-executable-size-visualization-with-d3.html#overview https://science.raphael.poss.name/go-executable-size-visuali...
- justinsaccount 8y agoapache2 is mostly modules that are loaded at runtime.
- takeda 8y agoOn my FreeBSD machine, all files in the entire apache package (including modules, manpages, headers, default pages, graphic for displaying directories in gif and png formats, tools are) take 4.3MB
- sagichmal 8y agoFor self-contained architecture-specific server binaries, there is no practical difference between 240KB, or 2.4MB, or 24.4MB, or even, at a stretch, 244MB. It's not worth mentioning or optimizing for, except as novelty. I wish people would stop golfing with these numbers.
- takeda 8y agoYou have it backwards, apache or nginx size is not for the novelty. Go is just a pig and its size grows every new release, and the size isn't really for being statically linked or debugging symbols, because it's huge even when those options are disabled. Right now a "hello world" application in Go has comparable size to an OS with full GUI.
- sagichmal 8y agoWho cares? Literally, what problem does it cause, or what does it make worse? It is totally immaterial.
- takeda 8y ago- increases amount of time to fetch and run container (it actually is quite noticeable when you have app that scales out and you updating it) - it increases amount of storage to store multiple versions of containers (when you have an internal app and do frequent releases it adds quickly) - it increases amount of data transferred on every deployment - increases amount of memory used (the whole point of containers, was to efficiently use hardware (BORG), although a lot of people today miss that reason and run containers on VMs)
- Go0the0gophers 8y agoLol, I let you use java spring boot technology. It is really bloat (ram, cpu, disk, infamous slowly startup and jit optimization, complex tuning eg. thread pool and so on). Good luck.
- yetanotherme 8y ago
- Propolice 8y agoAlgernon does a bit more than plain Nginx or Apache. 24.4 MiB also includes bloat. See: https://github.com/golang/go/issues/27266 https://github.com/golang/go/issues/27266 https://github.com/golang/go/issues/2559 https://github.com/golang/go/issues/2559 Hopefully we can get smaller binaries by Go 1.13.
- takeda 8y agoMy Apache installation with modules takes 4.3MB, and I'm quite sure Apache with modules can do more than Algernon.
- xyproto 8y agoAlgernon would be a lot smaller if it was not statically compiled and compiled with gccgo instead. Sadly, the Go package that provides support for QUIC does not compile with gccgo, yet.
- chvid 8y agoI don't think it is fair that you are being downvoted. Size does matter and not just in sense that it is using resources. The largest part of the 24 MB probably never gets executed but it adds unnecessary complexity that may hide bugs and security flaws.
- xyproto 8y agoThe docker image is 9MB. https://hub.docker.com/r/xyproto/algernon/tags https://hub.docker.com/r/xyproto/algernon/tags
- tyingq 8y ago"Files that are sent to the client are compressed with gzip, unless they are under 4096 bytes." That's interesting. Is that a common optimization? I hadn't heard of any other web server doing that.
- hombre_fatal 8y agoI'd be surprised if it didn't exist in every compression middleware. For example, https://github.com/expressjs/compression/blob/dd5055dc92fdeacad706972c4fcf3a7ff10066ef/index.js#L55 https://github.com/expressjs/compression/blob/dd5055dc92fdea...
- tyingq 8y agoI don't see anything like that documented for apache's mod_deflate/zlib.
- hombre_fatal 8y agoSeems not, but there is for mod_gzip for example. I'd definitely consider it common.
- nnx 8y agoNginx uses a similar optimization with a configurable threshold defaulted to 1kb.
- nodesocket 8y agoCorrect, the NGINX configuration should be something like: gzip on; gunzip on; gzip_http_version 1.1; gzip_proxied any; gzip_comp_level 5; gzip_disable "msie6"; gzip_vary on; gzip_min_length 2048;
- arkadiyt 8y agoCloudfront is similar [1]: > The file size must be between 1,000 and 10,000,000 bytes. [1]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html https://docs.aws.amazon.com/AmazonCloudFront/latest/Develope...
- marcus_holmes 8y agoI wonder why they didn't include Let's Encrypt integration - it's completely painless using the acme library, and that would prevent the whole "HTTP or HTTPS?" discussion around HTTP/2
- xyproto 8y agoIt's in progress. Algernon is an open source project where I am the main contributor, and I develop Algernon in my spare time. Pull requests are welcome.
- marcus_holmes 8y agoI'd love to help, but my coding time is already taken building a product. I pretty much followed the instructions here: https://godoc.org/golang.org/x/crypto/acme/autocert https://godoc.org/golang.org/x/crypto/acme/autocert edit, better here: https://blog.kowalczyk.info/article/Jl3G/https-for-free-in-go-with-little-help-of-lets-encrypt.html https://blog.kowalczyk.info/article/Jl3G/https-for-free-in-g... I didn't believe it could be that simple, but it worked first time and has proven really robust.
- erdii 8y agoIt is even easier: https://github.com/mholt/certmagic https://github.com/mholt/certmagic Edit: Taken from certmagic docs Instead of: // plaintext HTTP, gross http.ListenAndServe(":80", mux) Use CertMagic: // encrypted HTTPS with HTTP->HTTPS redirects - yay! certmagic.HTTPS([]string{"example.com"}, mux)
- a_imho 8y agoHow does this compare to OpenResty?
- DarkWiiPlayer 8y agoI suppose this one offers an all-in-one package, while openresty is really just an nginx server with builtin Lua(JIT) support.
- deleted 8y ago[deleted]
- mtw 8y agoWhat is the benefit of using this? In what scenario would this excel? Thanks.
- xyproto 8y agoGood question. I'm not sure if it excels in any scenario. There are specialized web servers that excel at caching or at raw performance. There are dedicated backends for popular front-end toolkits like Vue or React. There are dedicated editors that excel at editing and previewing Markdown, or HTML. I guess the main benefit is that Algernon covers a lot of ground, with a minimum of configuration, while being powerful enough to have a plugin system and support for programming in Lua. There is an auto-refresh feature that uses Server Sent Events, when editing Markdown or web pages. There is also support for the latest in Web technologies, like HTTP/2, QUIC and TLS 1.3. The caching system is decent. And the use of Go ensures that also smaller platforms like NetBSD and systems like Raspberry Pi are covered. There are no external dependencies, so Algernon can run on any system that Go can support. The main benefit is that is is versatile, fresh, and covers many platforms and use cases. For a more specific description of a potential benefit, a more specific use case would be needed.