Traefik vs Nginx as a reverse proxy for multiple Docker containers in production
By Kevin Marcondes · Published on · Updated on · 8 min read
Traefik vs Nginx as a reverse proxy for multiple Docker containers in production: which one should you pick? If you need automatic discovery via labels and built-in TLS, Traefik often makes operations simpler. If you want fine-grained control and maximum predictability with traditional configuration, Nginx is rock-solid. Below are clear criteria, configuration examples and how to test performance.
Quick summary: when to choose each
Both provide reverse proxying and load balancing. The main differences are operational model and how configuration flows in a Docker environment. Use this guidance as a starting point and validate in your context:
Traefik integrates with Docker natively via labels and renews certificates automatically. Nginx gives you detailed control but requires extra automation to reflect container changes without manual reloads.
- Choose Traefik if you want automatic discovery via labels and integrated HTTPS with Let's Encrypt.
- Choose Nginx if you need advanced directives and predictable behavior through static files.
- Both handle high traffic well; test with your workload before making a final decision.
- Both support HTTP/2 and HTTP/3 in recent builds, depending on build and configuration.
Comparison table: practical criteria
This Traefik vs Nginx comparison for reverse proxying multiple Docker containers in production lines up the points that most affect operations. Use the table as a checklist when building your deploy pipeline and configuration governance.
| Criterion | Traefik | Nginx |
|---|---|---|
| Service discovery (Docker) | Native via labels, no reload | Not native; requires reload/sidecar |
| Dynamic configuration | Hot-reload via Docker provider | Static files; reload to apply |
| Let's Encrypt | Integrated (ACME) | External (e.g. Certbot) |
| Routing (host, path, headers) | Declarative rules and middlewares | Flexible directives via server/location |
| HTTP/2 and HTTP/3 | Available in recent versions | Available in recent versions |
| Observability | Built-in metrics/health | stub_status/exporters (configure) |
| Raw performance in simple cases | Very good; low overhead | Excellent in static/simple scenarios |
| Learning curve | Fast in Docker (labels) | Requires knowledge of directives and blocks |
| Frequent changes (scale) | Automatic, no manual intervention | Requires reload automation |
| Blue/Green and canary | Routing via rules and weights | Possible with upstreams and maps |
Architecture and service discovery with Docker
With Traefik, the Docker provider reads container labels and creates routes automatically. That reduces auxiliary scripts and reloads. In Nginx, host resolution happens when the configuration is parsed. IP changes require reloading the process or external tooling to regenerate the file.
This detail matters in environments with elastic scaling or frequent rollouts. In stable environments, Nginx with well-versioned configuration is simple and predictable.
Example: Traefik with labels and automatic HTTPS (Docker Compose)
This compose exposes Traefik on ports 80/443, issues certificates via ACME and publishes two services by host. Replace domains and ports to match your app. Exposing the docker.sock carries risks; use read-only or a socket-proxy. If you need to install Docker/Compose, see the guide: install Docker and Docker Compose.
version: "3.8"
networks:
web:
external: false
services:
traefik:
image: traefik:v2.10
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- [email protected]
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.le.acme.httpchallenge=true
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik_letsencrypt:/letsencrypt
networks:
- web
app1:
image: ghcr.io/org/app1:latest
labels:
- traefik.enable=true
- traefik.http.routers.app1.rule=Host(`app1.example.com`)
- traefik.http.routers.app1.entrypoints=websecure
- traefik.http.routers.app1.tls.certresolver=le
- traefik.http.services.app1.loadbalancer.server.port=3000
networks:
- web
app2:
image: ghcr.io/org/app2:latest
labels:
- traefik.enable=true
- traefik.http.routers.app2.rule=Host(`api.example.com`) && PathPrefix(`/v1`)
- traefik.http.routers.app2.entrypoints=websecure
- traefik.http.routers.app2.tls.certresolver=le
- traefik.http.services.app2.loadbalancer.server.port=8080
networks:
- web
volumes:
traefik_letsencrypt:
Example: Nginx as reverse proxy for multiple services
Here is a minimal nginx.conf with two server blocks. Nginx and target containers should be on the same Docker network. When IPs or scale change, you’ll need to automate Nginx reloads to reflect new backends. Portainer can help manage containers: use Portainer to manage Docker.
worker_processes auto;
error_log /var/log/nginx/error.log warn;
events { worker_connections 1024; }
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
map $http_x_forwarded_proto $upstream_proto { default http; https https; }
server {
listen 80;
server_name app1.example.com;
location / {
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;
proxy_pass http://app1:3000;
}
}
server {
listen 80;
server_name api.example.com;
location /v1/ {
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;
proxy_pass http://api:8080;
}
}
}
TLS, HTTP/2/3 and operational security
Traefik issues and renews certificates via ACME without external jobs. With Nginx you can use an ACME client (like Certbot) and point keys in the server block. In both, enable HTTP/2 and, where feasible, HTTP/3 on supported versions. For fundamentals and certificate automation, see: get free SSL with Let's Encrypt.
Harden the edge: enforce strong TLS, limit headers, configure timeouts and body size. Keep images updated and monitor CVEs. In Traefik, middlewares help standardize policies. In Nginx, use directives and versioned includes.
Performance and how to test before deciding
For simple pass-through or static content proxying, Nginx tends to achieve very high throughput with low latency. In environments with dynamic rules and many changing services, Traefik keeps operational agility with consistent performance. When evaluating Traefik vs Nginx as a reverse proxy for multiple Docker containers in production, run controlled tests.
Load testing: run tests from a network close to the service, with realistic connections and duration. Vary HTTP/1.1, HTTP/2 and TLS. Compare CPU, memory and latency under the same hardware. Commands of reference are below.
# Hey (HTTP)
docker run --rm rakyll/hey -z 30s -c 200 https://app1.example.com/api/health
# wrk (HTTP/1.1 e TLS via openssl)
wrk -t4 -c200 -d30s --latency https://app1.example.com/
# Dica: execute os testes para Traefik e Nginx sob a mesma carga e máquina.
Observability, logs and metrics in production
Log request correlation and structured fields to inspect bottlenecks behind the proxy. Traefik exposes metrics ready for common collectors. With Nginx, expose a status endpoint and use exporters. Centralize logs in JSON and apply sampling at high volume.
To implement structured logs and request correlation in the backend, see this guide: structured JSON logs and request correlation. Integrate the proxy into your existing observability pipeline.
Operational costs, governance and change flow
Traefik simplifies day-to-day operations when teams publish new services frequently via labels in Compose/Swarm/K8s. Fewer files to regenerate and fewer reload windows. Nginx shines when you need very specific rules, filters and fine tuning by directive.
Regardless of choice: version configuration, test in staging, automate health checks and rollbacks. If you're still building the base environment, these resources help: install Docker and Docker Compose.
Frequently asked questions
Is Traefik or Nginx faster as a reverse proxy?
It depends on workload and configuration. For simple pass‑through or static content proxying, Nginx typically achieves very high throughput and low latency. In environments with many dynamic services or frequent changes, Traefik reduces operational overhead through automatic discovery and built‑in certificate handling, keeping performance consistent. Run controlled load tests with your real traffic to compare CPU, memory and latency under the same conditions.
Can I use automatic Let's Encrypt with Nginx?
Yes. Nginx does not include an ACME client, so you obtain and renew certificates with an external tool (for example Certbot) and reference the key and certificate files in the server blocks. Traefik, by contrast, integrates ACME natively and automates issuance and renewal, which simplifies certificate management in dynamic Docker environments. Ensure your renewal process is tested and monitored.
Do Traefik and Nginx support HTTP/3 (QUIC)?
Both can support HTTP/3 (QUIC) in recent versions, but support depends on the build and configuration. Verify that the proxy binary includes QUIC support, enable the required parameters and expose the appropriate UDP ports. Update firewalls, test client compatibility, and monitor latency and error rates, since behavior and benefits can vary by workload and client environment.
How to enable automatic container discovery in Nginx?
Plain Nginx does not observe Docker events. To enable automatic discovery you need tooling that regenerates Nginx configuration and triggers reloads when containers start, stop or change IPs — for example CI/CD scripts, service registries or sidecar/agent patterns. Alternatively, use an orchestrator that integrates with the proxy, or choose Traefik, which reads Docker labels and creates routes without external regeneration.
Is it safe to mount the docker.sock in Traefik?
Mounting docker.sock exposes the Docker API and therefore broad control over the host and containers; it is considered risky. If you must mount it for Traefik, minimize exposure: use read‑only where supported, place a socket‑proxy that limits allowed calls, apply least privilege, and monitor audit logs. Evaluate alternatives before granting Docker API access to a networked service.
Need help choosing your production reverse proxy?
We can assess your traffic, TLS/routing requirements and deploy flow to recommend the best option between Traefik and Nginx and prepare the environment following best practices.
Discuss proxy architecture