I suspect that people don't like changing web servers, and perhaps that's why it took the industry so long to move away from Apache. Ferron actually looks great — great performance, automatic TLS, easy reverse proxy configuration and more. Congrats on shipping this!
Please consider out-of-the-box way to analyze slow queries, analysis by endpoints (ideally with some patterns to group by), ideally to not generate gigabytes of access logs but rather give some already-aggregated in-memory stats.
Maybe batteries included would be great (web UI similar to HAProxy but way-way better).
I am a FOSS developer myself for many years, and this is exactly kind of stuff I'd love to hear. So no, it is totally OK to give your ideas to the developer in this form.
I’d love your opinion on how you found working with Rust’s memory model for something like a web server. Did your design fit naturally with ownership and borrowing, or did you find yourself fighting the language?
I wouldn't. Blazing fast, fearless concurrency, etc. are all super cringe at this point. Just say it's fast, secure and reliable or something like that.
Thank you for the feedback! I think this is an advantage of Rust that prevents common pitfalls related to concurrent programming, making web servers written in Rust safer.
Deadlocks are easy to debug and fix. Data races are not. There are also tools like tracing mutex to catch deadlocks more easily at runtime without necessarily encountering it.
Yes, I know that both Axum and Actix Web exist. However, these are web application frameworks designed for building web applications in Rust. On the other hand, my project is a standalone web server, similar to Apache httpd, NGINX, or Caddy.
While there are standalone web servers in Rust, such as Static Web Server and binserve, they primarily focus on serving static files rather than providing general-purpose web hosting capabilities. My goal is to create a more versatile web server that can handle a wider range of web hosting applications.
Pingora is not a standalone web server (like NGINX or Apache httpd), it's a Rust-based framework developed by Cloudflare for building network services, particularly HTTP proxies.
River (built on Pingora) is designed to be a reverse proxy. My web server on the other hand is designed to be a general-purpose web server (it also supports reverse proxying).
It sounds like this is a general purpose web server rather than a web framework like axum and actix-web. It's in the category of nginx, apache or caddy.
This web server is probably awesome. However "memory-safe" isn't distinguishing within the Rust ecosystem. There's... a lot... of Rust web servers out there, all of which are presumably memory-safe, because Rust:
Thank you! Many other web server written in Rust are memory-safe as well, because of Rust's borrow checker.
I designed Ferron to be a general-purpose, standalone web server, just like NGINX or Caddy. It can even run PHP web applications (through FastCGI).
You’re right, but the state of play is even better than you suggest because there’s a lot of memory safe web servers outside of Rust too. Eg Go.
And that’s not even counting all the webservers included as part of their backend frameworks in Python, node.js, Java, etc.
web servers written in unsafe languages are really the minority but those that do exist are largely so heavily battle tested that a rewrite would likely introduce new sources of bugs (eg Apache and nginx).
If there’s one domain that’s seen a lot of competition for security, it’s been web servers.
I was looking for a web server, not a web framework. A replacement for nginx and caddy, not something to build applications on thus I never would have thought about clicking on a link talking about web frameworks.
Anybody have any suggestions beyond the one under discussion?
I use caddy and I'm quite happy with it over apache and nginx, but I'd happily give my opinion if this helps OP to make this something different and hopefully even better than caddy.
I love auto TLS and caddyfiles are easy to understand. Modularity is important and templates can be very useful. Serving files and using caddy as reverse proxy are the most common uses I make of it in production, but I also use caddy in dev and it's a boon. Ease of config means my team can easily pick up my work and continue from there, even if they are not as proficient with the tool.
I don't love caddyfile directive ordering: sometimes my colleagues are confused because directives have an implicit order that is not obvious: instead of reordering directives, I'd rather have a warning/error message saying "this config doesn't make sense because you cannot do this and that", or just follow the order used in the config file + warnings.
I use it a lot to prototype and mock APIs during development, e.g. to have endpoints returning html pages or json documents: static files and templates are useful for this and I wouldn't consider something without this feature, though go templates aren't that great and/or caddy docs are a bit lacking (e.g. a simple loop over 0,1,2,3... Is not obvious!)
I don't find caddy great (or I don't know how to use it) to debug things when they are not working as expected. I often find myself replacing parts of the infra with netcat so that I can inspect what is going on. It would be great to have a "debug endpoint", like a webpage I could connect to and inspect all the traffic like MITM proxy, it would be awesome. Being able to inject myself in a route and manually change headers, responses, requests etc, it would be fantastic and a great help in debugging issues. Also, being able to start this "inspection mode" while in production would be nice, without having to restart the server (something is off -> I ssh-port-forward to the server host -> connect my browser to the server and inspect the errors -> find the issue and fix the config).
Management of certs could be improved in some edge cases. For example, I'd be happy if it was easier to manage certs in a private subnet. For example, say host A could acquire certs for my domain example.com with DNS challenge, then a host B, not public facing but in a subnet with A, could ask A to manage its certificates and still have valid https (letsencrypt provided certs) inside the network.
One thing I also don’t like in caddy is the lack of caching configuration available without using a partially implemented extension. I find it quite important as a reverse proxy with nginx.
I agree with the implicit ordering of marchers in caddy.
Also, while I love Rust and I'm a big fan of the language, please stop saying "it's made with Rust!". Really, it's only annoying and irrelevant to the quality of a project and it might even be counterproductive. Who cares what language is used for a software as long as it works great ;)
This holds in general, not only for this project in particular.
I see that it's written in Rust, besides that, what's your ambition for why an end user would choose this project over one of the established players like Caddy/Traefik/nginx?
I think for this web server to compete with caddy/nginx (if the goal is getting other people to use it, if built for fun, please ignore) this needs a good reason to exist.
Memory-safe is nice compared to Nginx, but pretty moot when comparing to Caddy. OTOH, perhaps this could aim for better/comparable performance to Nginx (and better than Caddy) whilst being memory safe? It’s still quite a niche use case though.
As welcome as the efficiency and performance features are, the convenience of lets encrypt integration in Caddy wins the decision almost all the time. No more certbot cron jobs or worries about having the certs in the right place or permissions etc.
for this to be equivalent to Caddy, that is the most important convenience feature.
I apologise for my low quality comment. I only read the website and did not actually try the web server. It wasn’t highlighted on the homepage(like Caddy does) and I made a tardy assumption.
- Since this is Hacker News, it's likely meant to showcase it to other Rust engineers, or attract contributors
- It signals that it is close to C/C++ speeds, but is more memory-safe than C/C++ servers
- It shows pride in being able to overcome the borrow checker, which can sometimes be difficult (Rust is more of a language + small formal proof of memory safety, than just a language)
I don't mind it, since I like the language, and I'll try to use apps written in Rust when possible. If I see Rust, I know what to expect wrt. resource usage and performance, contributor experience and so on. I'm also willing to test them to "dog-food" the ecosystem.
By default, I expect that the performance, memory usage and start-up time of a Rust app to be comparable to an equivalent one written in C or C++. That's still a range of one or two orders of magnitude, but it's still good enough to have an initial idea.
For example, there's a popular Python app that used to take 1-2 seconds just to display the help message. It's a little better these days, and I'd use it anyway there's no alternative, but there's no way a Rust version of it would be that slow to start.
reply