3 ms·
What upsets me about Nginx the most is that it takes the fail-fast approach, which isn't entirely suitable for combining it with a container workflow, at least
by KronisLV 5y ago
What upsets me about Nginx the most is that it takes the fail-fast approach, which isn't entirely suitable for combining it with a container workflow, at least in situations where you're running it without something like Kubernetes (which has its own customizations).
For example, currently i run my own Nginx ingress with Docker Swarm:
service A / B / C <--> Nginx <--> browser
The reverse proxy configuration feels easier to do than that of Apache2/httpd, for example:
server {
listen 80;
server_name app.test.my-company.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name app.test.my-company.com;
# Configuration for SSL/TLS certificates
ssl_certificate /app/certs/test.my-company.com.crt;
ssl_certificate_key /app/certs/test.my-company.com.key;
# Proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Reverse proxy
location / {
resolver 127.0.0.11 valid=30s; # Docker DNS
proxy_pass http://my-app:8080/;
proxy_redirect default;
}
}
However, suppose that the "my-app" container has a health check set up for it. What does that mean? Docker Swarm won't route any traffic to it until it's finished initialization. Except that it also means that DNS requests won't return anything for "my-app" until at least one healthcheck passes. That in of itself shouldn't be too problematic, right? Any web server surely would just log that one request as an error and return an error until eventually everything would work.
Wrong. Nginx does throw the error and the request fails, but the ENTIRE web server goes down:
nginx: [emerg] host not found in upstream "my-app"
What does that mean? If you have 1 Nginx instance on the server that needs to proxy 10 apps in total, one app not being available will prevent the other 9 from working! Whoever thought that such defaults would be okay has reasoning that is beyond me, especially considering that the Caddy web server does something similar and will go down if 1 out of 10 sites fails to provision the SSL/TLS certificate, instead of letting the others work - completely opposite of what someone who cares about resiliency would want!
But fear not, supposedly there's a solution!
# Reverse proxy
location / {
resolver 127.0.0.11 valid=30s; # Docker DNS
set $proxy_server my-app;
proxy_pass http://$proxy_server:8080/;
proxy_redirect default;
}
Except that, you know, that also doesn't work:
nginx: [emerg] "proxy_redirect default" cannot be used with "proxy_pass" directive with variables
Now, that's not an issue in my case, since i just jotted down the "proxy_redirect default;" value to remember what it does, but it's unfortunate to hear that it is neither ignored (since it's the default value which is functionally identical to it not being there), nor could other values be used: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect http://nginx.org/en/docs/http/ngx_http_proxy_module.html#pro...
In summary, it's nice that there are workaround for problems like that, but it's a bit odd that the web server is otherwise so quick to fall over and die, as well as the fact that the defaults aren't oriented towards maximum reliability and resilience. That said, i still do like Nginx and actually wrote about how to use it as a reverse proxy on my blog a while back: https://blog.kronis.dev/tutorials/how-to-use-nginx-to-proxy-your-front-end-and-back-end https://blog.kronis.dev/tutorials/how-to-use-nginx-to-proxy-...
But at the same time, in situations where load isn't high enough for the web server to be the bottleneck, it's also helpful to evaluate the alternatives, notably: Apache2/httpd, Caddy and Traefik. It was actually pretty recently that Apache2/httpd got mod_md, which allows provisioning Let's Encrypt certificates out of the box, which is certainly promising: https://httpd.apache.org/docs/trunk/mod/mod_md.html https://httpd.apache.org/docs/trunk/mod/mod_md.html
- contravariant 5y agoIt's also nice that this means you basically can't use the keepalive setting they mention in this article. Or rather you can but apparently you need the expensive version of nginx to be able to have upstream servers that resolve hostnames sensibly.
- mholt 5y ago> especially considering that the Caddy web server does something similar and will go down if 1 out of 10 sites fails to provision the SSL/TLS certificate What? That's not true. From the Caddy docs [1]: > Caddy does its best to continue if errors occur with certificate management. By default, certificate management is performed in the background. This means it will not block startup or slow down your sites. However, it also means that the server will be running even before all certificates are available. Running in the background allows Caddy to retry with exponential backoff over a long period of time. Caddy will actually keep your site online when other servers don't. See the bottom of this page: https://caddyserver.com/v2 https://caddyserver.com/v2 [1]: https://caddyserver.com/docs/automatic-https#errors https://caddyserver.com/docs/automatic-https#errors