MinIO/S3-backed static hosting using Traefik reverse proxy + nginx-s3-gateway
The following docker-compose.yml
uses nginx-s3-gateway
to proxy HTTP requests to a configured S3-compatible storage backend (in this case, MinIO). This provides production-ready performance supported by Nginx, Inc., plus high configurability since internally, nginx-s3-gateway
is using nginx
, so it can flexibly be configured.
See Simple Traefik docker-compose setup with Lets Encrypt Cloudflare DNS-01 & TLS-ALPN-01 & HTTP-01 challenges for details on how we setup Traefik to work with these container labels.
services:
s3-gateway:
image: nginxinc/nginx-s3-gateway:latest
environment:
# Required (see repo docs)
S3_BUCKET_NAME: "mydomain-app"
AWS_ACCESS_KEY_ID: "mydomain-app-reader"
AWS_SECRET_ACCESS_KEY: "Ooch7rooD8yo8ooW6ohghahNgaeshu"
S3_SERVER: "minio.mydomain.com"
S3_REGION: "eu-central-1"
S3_STYLE: "path"
S3_SERVER_PORT: "443"
S3_SERVER_PROTO: "https"
AWS_SIGS_VERSION: "4"
PROVIDE_INDEX_PAGE: true
ALLOW_DIRECTORY_LIST: "false"
labels:
- "traefik.enable=true"
- "traefik.http.routers.app-mydomain.rule=Host(`app.mydomain.com`)"
- "traefik.http.routers.app-mydomain.entrypoints=websecure"
- "traefik.http.routers.app-mydomain.tls.certresolver=cloudflare-ec384"
- "traefik.http.routers.app-mydomain.tls.domains[0].main=mydomain.com"
- "traefik.http.routers.app-mydomain.tls.domains[0].sans=*.mydomain.com"
Benchmark results
Using wrk
to benchmark this. The server is running on a AMD Ryzen 5 3600 6-Core Processor
with exclusively HDDs (no SSDs), with MinIO serving the S3 bucket over HTTPS, leading . The client is connected over a routed network with 0.3ms ping latency.
$ wrk -t20 -c1000 -d30s --latency https://my.domain.com
Running 30s test @ https://my.domain.com/
20 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 55.16ms 77.11ms 1.92s 96.45%
Req/Sec 289.80 88.91 630.00 72.58%
Latency Distribution
50% 41.14ms
75% 53.31ms
90% 86.89ms
99% 439.90ms
171457 requests in 30.09s, 1.01GB read
Socket errors: connect 0, read 0, write 0, timeout 850
Non-2xx or 3xx responses: 6
As can be seen from the results, the setup is capable of handling a extreme load with reasonable latency and low error rate, even given the suboptimal HDD-only configuration plus additional TLS-to-MinIO overhead, making it suitable for production use cases.