linguaielts-api / nginx.docker.conf
AnhviNguyen
fix: db connection pool, utf-8 bom, auth refresh endpoint
cd31784
Raw
History Blame Contribute Delete
3.74 kB
# Reverse proxy for Docker Compose (HTTP only — add SSL at host/load balancer in real prod)
# Use Docker DNS with short TTL so gateway picks up new container IPs after rebuild.
# SPA dashboard fires many parallel /api calls on load — keep auth/ML strict, API generous.
limit_req_zone $binary_remote_addr zone=docker_auth:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=docker_api:10m rate=600r/m;
limit_req_zone $binary_remote_addr zone=docker_ml:10m rate=3r/m;
server {
listen 80;
client_max_body_size 16M;
resolver 127.0.0.11 valid=10s ipv6=off;
resolver_timeout 5s;
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; media-src 'self' data: https: blob:; connect-src 'self' https://accounts.google.com https://www.youtube.com https://www.googleapis.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://api.fontshare.com; font-src 'self' https://fonts.gstatic.com https://cdn.fontshare.com; script-src 'self' https://www.youtube.com https://s.ytimg.com; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com; frame-ancestors 'none'";
location /api/ {
limit_req zone=docker_api burst=120 nodelay;
set $api_backend api:8000;
proxy_pass http://$api_backend;
proxy_http_version 1.1;
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_read_timeout 300s;
}
location ~ ^/api/(auth/login|auth/register|auth/forgot-password)$ {
limit_req zone=docker_auth burst=5 nodelay;
set $api_backend api:8000;
proxy_pass http://$api_backend;
proxy_http_version 1.1;
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;
}
location ~ ^/api/(speaking/evaluate|shadowing/pronunciation/check|vocabulary/pronunciation/check|pronunciation/word|conversation/turn/voice)$ {
limit_req zone=docker_ml burst=2 nodelay;
set $api_backend api:8000;
proxy_pass http://$api_backend;
proxy_http_version 1.1;
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_read_timeout 300s;
}
location /uploads/ {
set $api_backend api:8000;
proxy_pass http://$api_backend$uri$is_args$args;
proxy_set_header Host $host;
add_header Cache-Control "public, max-age=86400";
}
location /audio/ {
set $api_backend api:8000;
proxy_pass http://$api_backend$uri$is_args$args;
}
location /images/ {
set $api_backend api:8000;
proxy_pass http://$api_backend$uri$is_args$args;
}
# Legacy thumbnail URLs (/api/images/{uuid}) → same handler as /images/
location /api/images/ {
set $api_backend api:8000;
rewrite ^/api/images/(.*)$ /images/$1 break;
proxy_pass http://$api_backend;
proxy_set_header Host $host;
}
location / {
set $frontend_backend frontend:80;
proxy_pass http://$frontend_backend$uri$is_args$args;
proxy_set_header Host $host;
}
gzip on;
gzip_types text/plain application/json application/javascript text/css;
}