featured image

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 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:

  1. 413 Request Entity Too Large (file upload limits)
  2. Serving static files without extensions (e.g., .well-known/apple-app-site-association)
  3. 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.

Nginx Working

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

ProblemError / SymptomRoot CauseFix LocationConfig File
File Upload Limit413 Request Entity Too LargeDefault body size too small/etc/nginx/vhost.d/example.com
Static File HandlingMissing static files or 404sApp doesn’t serve extensionless files/usr/share/nginx/html/ & /etc/nginx/vhost.d/example.com
Timeout Issues504 Gateway TimeoutDefault proxy timeout too short/etc/nginx/vhost.d/domain.com

5. Problem 1 — 413 Request Entity Too Large (File Uploads)

Problem 1

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:

  1. Create a file named after your domain:

    touch vhost.d/example.com
  2. Add this directive:

    client_max_body_size 50M;
  3. 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
  4. 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)

Problem 1

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:

  1. Create a local folder to store your static content:

    mkdir -p html/.well-known
  2. Place your static file there:

    html/.well-known/apple-app-site-association
  3. Add a domain-specific location config file:

    touch vhost.d/example.com
  4. 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;
    }
  5. 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)

Problem 1

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:

  1. Create a domain-specific configuration file:

    touch vhost.d/example.com.conf
  2. Add these directives:

    proxy_read_timeout 300;
    proxy_send_timeout 300;
  3. Mount the directory in your Compose file:

    services:
      nginx-proxy:
        image: nginxproxy/nginx-proxy
        volumes:
          - ./conf.d:/etc/nginx/conf.d
  4. 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

AspectManual Nginx Configurationnginx-proxy Container
ConfigurationRequires writing .conf files manuallyAuto-generated from Docker environment variables
ScalabilityDifficult to manage for multiple appsAutomatically scales with running containers
SSLManual setup using Certbot or OpenSSLAutomated with acme-companion and Let’s Encrypt
MaintenanceFrequent manual updates and reloadsAutomatic reload on container start/stop
FlexibilityFull control for advanced setupsLimited to supported options and overrides
SecurityNo Docker socket accessRequires Docker socket (potential security concern)
Ideal Use CaseLarge enterprise or custom Nginx tuningSmall 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.

Next
PDF to Markdown Conversion Tools: Beyond the Hype - A Deep Dive into MarkItDown, Docling, and Mistral Document AI