Looking for a new reverse proxy
The majority of container setups need a reverse proxy to redirect incoming requests to the appropriate container. I use Dotege, a template generator that listens to container events and creates a config, this gives me the flexibility to switch proxies easily and try new things.
I was using Haproxy, but hit some irritating issues after a few releases and had to keep patching it to continue working. One bug prevented me from pushing containers to my registry, and another caused issues with my site's background rendering. Both changes were caused some major changes to how they handled one thing or another, but there are no tests to make sure it works correctly. Given this, I thought it was time to evaluate a replacement.
Benchmarking
To find the best proxy server, I decided to spin up a few instances of Dotege with different templates and run some benchmarks. I wanted to see how each proxy handled running my site and how easy they were to configure. I ran a 10-second test with 10 threads using wrk, a benchmarking tool. Whilst performance isn't everything, it is a fairly important part of the job. Here are the results of the benchmark tests:
|
Avg |
Stdev |
Max |
+/- Stdev |
Latency |
19.78ms |
8.64ms |
139.07ms |
75.39% |
Thread Req/sec |
50.95 |
12.40 |
180.00 |
82.14% |
Total Req/sec |
5193.85 |
|
|
|
Config
|
Avg |
Stdev |
Max |
+/- Stdev |
Latency |
24.52ms |
11.16ms |
89.78ms |
70.00% |
Thread Req/sec |
40.99 |
10.62 |
120.00 |
63.67% |
Total Req/sec |
4163.63 |
|
|
|
Config
|
Avg |
Stdev |
Max |
+/- Stdev |
Latency |
25.12ms |
13.36ms |
190.05ms |
72.82% |
Thread Req/sec |
40.29 |
13.93 |
140.00 |
78.02% |
Total Req/sec |
4097.49 |
|
|
|
Config
|
Avg |
Stdev |
Max |
+/- Stdev |
Latency |
29.65ms |
11.71ms |
198.40ms |
73.94% |
Thread Req/sec |
33.75 |
9.17 |
111.00 |
75.97% |
Total Req/sec |
3412.71 |
|
|
|
Config
|
Avg |
Stdev |
Max |
+/- Stdev |
Latency |
42.83ms |
30.42ms |
455.54ms |
90.41% |
Thread Req/sec |
25.69 |
9.44 |
120.00 |
74.22% |
Total Req/sec |
2529.13 |
|
|
|
Static Config Dynamic Config
|
Avg |
Stdev |
Max |
+/- St dev |
Latency |
50.25ms |
18.75ms |
159.01ms |
68.96% |
Thread Req/sec |
19.83 |
6.84 |
80.00 |
60.57% |
Total Req/sec |
2017.68 |
|
|
|
Config
Summary
- Haproxy: As expected, Haproxy performed well. It's a well-established and optimized proxy server. Haproxy isn't friendly to configure and it's very easy to introduce errors when you're trying new things.
- Apache and Nginx: Surprisingly, Nginx didn't perform as well as I expected. I spent some time optimizing it, but it still didn't match up to Apache. This made me re-evaluate my long-standing opinion that Nginx was faster than Apache. Config of these is fairly easy, and there's a huge community and loads of examples.
- Caddy and Traefik: These two proxies had similar performance. They are both standard and modern Go proxies with similar goals. However, Caddy offers more features for web serving. Caddy is very nice to configure and very flexible. Traefik isn't fun to configure, once you've got your head round things it makes sense, but it always seems to be a struggle.
- Centauri: This came in a close second, which was a surprise after the Caddy and Traefik results, and just ahead of apache and nginx. Configuration for this is very simple as it does one job, reverse proxy domains to another web server.
Looking at these results, it was a fairly easy choice to go with Centauri, it was the right combination of performance and ease to configure. It also doesn't help it's written by the author of Dotege, Chris Smith, so getting support for bugs should be fairly straightforward. This has been running a few weeks now and has yet to cause me any issues, so far so good.