Docker化Nginx修改client_max_body_size不生效,传大文件报413错误
问题场景
非Docker环境下,设置client_max_body_size 10m;能正常突破Nginx默认1MB的上传限制,但切换到nginx:latest Docker容器后,该配置完全无效,上传大于1MB的文件直接触发413 Request Entity Too Large错误。
当前环境:
- 三个Docker容器:Nginx、MariaDB、Express+PM2+Axios后端应用
- Express已配置上传限制:
app.use(express.json({ extended: true, limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' }));
- docker-compose.yml配置:
services: nginx: image: nginx:latest container_name: app_nginx restart: always ports: - 80:80 - 443:443 volumes: - ./nginx/conf.d/app.conf:/etc/nginx/conf.d/app.conf - ./nginx/ssl:/etc/nginx/ssl - ./nginx/logs:/var/log/nginx
- app.conf配置:
server { listen 443 ssl; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; location / { ... client_max_body_size 10m; ... } }
排查与解决步骤
补全80端口的配置
目前app.conf只配置了443端口的server块,如果请求走80端口(未跳转HTTPS),Nginx会用默认的80端口配置,而默认配置里的上传限制还是1MB。要么给80端口的server块也加client_max_body_size 10m;,要么在跳转HTTPS的同时带上该参数:server { listen 80; server_name 你的域名; client_max_body_size 10m; return 301 https://$server_name$request_uri; }把配置移到server级别
location级别的配置可能被其他规则覆盖,直接把client_max_body_size 10m;放到server块根目录,确保整个站点生效:server { listen 443 ssl; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; client_max_body_size 10m; # 移到这里 location / { ... # 移除location里的对应配置 ... } }验证配置并重启容器
进入Nginx容器检查配置语法是否正确:docker exec app_nginx nginx -t提示
test is successful后,重启Nginx容器:docker-compose restart nginx检查全局配置冲突
Nginx容器默认加载/etc/nginx/nginx.conf里的全局配置,里面可能已经设置了client_max_body_size,会覆盖你的自定义配置。进入容器查看该文件,如果有全局设置,要么修改全局值,要么在你的server块里明确设置来覆盖。确认请求走Nginx代理
检查Express应用的日志,确保请求是通过Nginx转发的,而不是用户直接访问了应用容器暴露的端口(绕开Nginx的话,上传限制就和Nginx无关了)。
内容的提问来源于stack exchange,提问作者Anil-shrestha

