Three Common Nginx Errors Solved: 413, 504, and Static File Handling (Docker Edition)
Fix Nginx errors like 413 Request Entity Too Large, 504 Gateway Timeout, and static file issues in Docker using simple nginx-proxy configuration tweaks.
Prathamesh Dhande Thu Nov 06 2025 00:00:00 GMT+0000 (Coordinated Universal Time) 5 min read 1. Introduction
When running applications inside Docker, managing Nginx configuration manually can quickly become painful, especially when dealing with multiple containers, domains, and SSL certificates.
That’s where the nginx-proxy Docker image comes in.
nginxproxy/nginx-proxy is a Docker image that automatically generates reverse proxy configurations for your containers based on environment variables like VIRTUAL_HOST and VIRTUAL_PORT. Combined with the nginxproxy/acme-companion image, it can even handle Let’s Encrypt SSL certificates automatically, no manual edits to nginx.conf required.
While this automation works for most cases, some issues still need manual tuning.
In this post, we’ll fix three of the most common Nginx problems developers face in Docker environments:
- 413 Request Entity Too Large (file upload limits)
- Serving static files without extensions (e.g.,
.well-known/apple-app-site-association) - 504 Gateway Timeout (long-running requests)
Each problem includes an explanation, root cause, and exact configuration fix using nginx-proxy.
2. What is Nginx and Why Write .conf Files Manually
Nginx is a high-performance web server and reverse proxy used to handle HTTP requests, balance load, serve static files, and manage SSL termination. Traditionally, system administrators configure Nginx by writing .conf files manually. These configuration files define server blocks, proxy routes, and SSL certificates.

Working of Nginx as a Reverse Proxy
For example, a typical manual Nginx configuration might look like this:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
While this provides complete control, it becomes tedious when working with multiple services or domains, as you must create and maintain a separate configuration for each one.
3. Overcoming Manual Configuration Using nginx-proxy
nginxproxy/nginx-proxy solves this problem by automatically generating Nginx configuration files based on Docker container metadata. When a container starts with specific environment variables, nginx-proxy detects it and updates Nginx dynamically without any manual .conf editing.
Example:
docker run -d -e VIRTUAL_HOST=api.example.com -e VIRTUAL_PORT=5000 my-api-app
The nginx-proxy container automatically creates a configuration that routes api.example.com to that container. When the container stops, the configuration is removed automatically.
This automation eliminates repetitive manual steps and ensures consistency across deployments.
4. Quick Reference Table
| Problem | Error / Symptom | Root Cause | Fix Location | Config File |
|---|---|---|---|---|
| File Upload Limit | 413 Request Entity Too Large | Default body size too small | /etc/nginx/vhost.d/ | example.com |
| Static File Handling | Missing static files or 404s | App doesn’t serve extensionless files | /usr/share/nginx/html/ & /etc/nginx/vhost.d/ | example.com |
| Timeout Issues | 504 Gateway Timeout | Default proxy timeout too short | /etc/nginx/vhost.d/ | domain.com |
5. Problem 1 — 413 Request Entity Too Large (File Uploads)

The Issue
When users upload large files (e.g., >1MB), Nginx may reject them with:
413 Request Entity Too Large
This happens because Nginx limits the request body size by default to prevent DoS attacks.
The Fix
You can override the limit per domain by mounting a custom configuration file into the nginx-proxy container.
Steps:
-
Create a file named after your domain:
touch vhost.d/example.com -
Add this directive:
client_max_body_size 50M; -
Mount this file inside your Docker Compose:
services: nginx-proxy: image: nginxproxy/nginx-proxy volumes: - /var/run/docker.sock:/tmp/docker.sock:ro - ./vhost.d:/etc/nginx/vhost.d -
Verify and reload Nginx:
docker exec -it nginx-proxy nginx -t docker exec -it nginx-proxy nginx -s reload
Result: Uploads up to 50 MB will now succeed without triggering a 413 error.
6. Problem 2 — Static File Handling (e.g., .well-known Files)

The Issue
You might need to serve static files (like .well-known/apple-app-site-association) for iOS or other services.
However, many frontend apps (like React or Angular) don’t serve these files, causing a 404 Not Found.
The Fix
Serve these files directly from Nginx rather than the app.
Steps:
-
Create a local folder to store your static content:
mkdir -p html/.well-known -
Place your static file there:
html/.well-known/apple-app-site-association -
Add a domain-specific location config file:
touch vhost.d/example.com -
Add this Nginx directive:
location /.well-known/apple-app-site-association { alias /usr/share/nginx/html/.well-known/apple-app-site-association; default_type application/json; try_files $uri =404; } -
Mount both directories in Docker Compose:
services: nginx-proxy: image: nginxproxy/nginx-proxy volumes: - ./vhost.d:/etc/nginx/vhost.d - ./html:/usr/share/nginx/html
Result: Nginx now serves static files directly, bypassing the application container.
7. Problem 3 — 504 Gateway Timeout (Long-Running Requests)

The Issue
When your backend performs heavy processing (e.g., generating reports or long database queries), Nginx may return:
504 Gateway Timeout
This means the reverse proxy closed the connection before the app responded.
The Fix
Increase Nginx proxy timeouts globally.
Steps:
-
Create a domain-specific configuration file:
touch vhost.d/example.com.conf -
Add these directives:
proxy_read_timeout 300; proxy_send_timeout 300; -
Mount the directory in your Compose file:
services: nginx-proxy: image: nginxproxy/nginx-proxy volumes: - ./conf.d:/etc/nginx/conf.d -
Verify and reload:
docker exec -it nginx-proxy nginx -t docker exec -it nginx-proxy nginx -s reload
Result: Nginx now waits up to 5 minutes for backend responses before timing out.
8. Pros and Cons: nginx-proxy vs Manual Nginx Configuration
| Aspect | Manual Nginx Configuration | nginx-proxy Container |
|---|---|---|
| Configuration | Requires writing .conf files manually | Auto-generated from Docker environment variables |
| Scalability | Difficult to manage for multiple apps | Automatically scales with running containers |
| SSL | Manual setup using Certbot or OpenSSL | Automated with acme-companion and Let’s Encrypt |
| Maintenance | Frequent manual updates and reloads | Automatic reload on container start/stop |
| Flexibility | Full control for advanced setups | Limited to supported options and overrides |
| Security | No Docker socket access | Requires Docker socket (potential security concern) |
| Ideal Use Case | Large enterprise or custom Nginx tuning | Small to medium Dockerized apps needing automation |
When to Use Which:
- Use nginx-proxy when you want simplicity, quick deployment, and automatic SSL for multiple containerized apps.
- Use manual Nginx configuration when you need fine-grained control over performance tuning, custom caching, or advanced routing.
Conclusion
Nginx is a reliable web server and reverse proxy, but managing it manually in Docker can be complex. The nginxproxy/nginx-proxy image automates configuration and SSL handling, reducing the need for manual setup. Applying these solutions for file uploads, static files, and timeouts ensures a smoother and more stable deployment.