I am currently an application with the following components, all running in docker containers on an AWS server:
- angularJs
- nodeJS
- nginx (using jwilder/nginx-proxy image)
- letsencrypt (using jrcs/letsencrypt-nginx-proxy-companion:v1.12 image)
The application allows me to upload files from the frontend, which sends them to an API endpoint in the nodeJs backend. Multiple files can be uploaded together, and these are all base64 encoded and sent in the same request.
When the files are small (up to about 5Mb total) this works perfectly fine, but recently I've tried slightly larger files (still less than 10Mb total) and I am experiencing the following error in my Chrome browser:
{"message":"request entity too large","additionalMessage":null,"dictionaryKey":"server_errors.general_error","hiddenNotification":false,"handledError":false}
Inspecting the traffic, I realised that the request was never making it to my backend, and thus assume that this error is caused by nginx blocking the request, presumably via the client_max_body_size property in my nginx config. Checking the logs of the nginx docker container, it doesn't actually show me any errors, but does warn that a tmp file is used (note I hgave masked IPs and URLs):
nginx.1 | 2021/11/12 03:19:15 [warn] 389#389: *9 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000001, client: 100.00.00.000, server: my-host-url.com, request: "POST /api/docs/upload HTTP/2.0", host: "my-host-url.com", referrer: "https://my-host-url.com/"
After some googling, I found and followed this article https://learn.coderslang.com/0018-how-to-fix-error-413-request-entity-too-large-in-nginx/ which explains the issue pretty clearly and even references the same docker image that I use. Unfortunately this has not fixed the issue. I also read the nginx docs which show that this property can be applied at
http, server, location
level, and so I updated my nginx config accordingly and restarted nginx on it's own, and also shut down and restarted the containers. Still no luck :(
My docker/nginx config is as follows, noting that I am now using client_max_body_size 0; to completely disable the check instead of just increasing the size
Docker compose
version: '2.4'
services:
nginx-proxy:
image: jwilder/nginx-proxy
environment:
# DEBUG: "true"
DEFAULT_HOST: my-host-url.com
ports:
- '80:80'
- '443:443'
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- nginx-certs:/etc/nginx/certs:ro
- nginx-vhost:/etc/nginx/vhost.d
- nginx-html:/usr/share/nginx/html
- ./nginx.conf:/etc/nginx/nginx.conf
sysctls:
- net.core.somaxconn=65536
mem_limit: 200m
labels:
- com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy
networks:
- common
restart: 'always'
logging:
options:
max-size: 100m
max-file: '5'
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion:v1.12
depends_on:
- nginx-proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- nginx-certs:/etc/nginx/certs:rw
- nginx-vhost:/etc/nginx/vhost.d
- nginx-html:/usr/share/nginx/html
# environment:
# DEBUG: "true"
networks:
- common
restart: 'always'
nginx.conf copied to container
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
client_max_body_size 0;
proxy_connect_timeout 301;
proxy_send_timeout 301;
proxy_read_timeout 301;
send_timeout 301;
include /etc/nginx/conf.d/*.conf;
server {
client_max_body_size 0;
location / {
client_max_body_size 0;
}
}
}
daemon off;