How do I customize my nginx configuration to modify the "client_max_body_size" in Elastic Beanstalk?

2 minute read
2

I want to upload large size files to my AWS Elastic Beanstalk environment without receiving the error message "413 Request Entity Too Large".

Short description

By default, NGINX has a limit of 1MB on file uploads. If the size of a request exceeds the configured value, then the 413 Request Entity Too Large error is returned. To upload files larger than 1 MB, configure the client_max_body_size directive in the NGINX configuration files.

Important: M and MB are equivalent expressions for "megabyte". For example, 2M is equal to 2 MB. However, use only M in your configuration file, as MB isn't valid in a configuration file.

Resolution

To configure the client_max_body_size in Amazon Linux 2 environments, do the following:

1.    To extend the Elastic Beanstalk default NGINX configuration, add the .conf configuration file client_max_body_size.conf that includes the following:

client_max_body_size 50M;

Note: In the preceding example, the value of the client_max_body_size is updated to 50M. Substitute any value in place of 50 as per your requirements.

2.    Copy the .conf configuration file client_max_body_size.conf to a folder named .platform/nginx/conf.d/ in your application source bundle. The Elastic Beanstalk NGINX configuration includes .conf files in this folder automatically. Make sure to create this path if it doesn't exist in your source bundle. The following example shows the structure of the .platform directory and .conf file in the application zip file:

-- .ebextensions
       -- other non nginx server config files
            
-- .platform
       -- nginx
           -- conf.d
                 -- client_max_body_size.conf
                   
-- other application files

The file client_max_body_size.conf has a path like this: my-app/.platform/nginx/conf.d/client_max_body_size.conf.

3.    Deploy your code and the new .platform/ directory together as a new application version in your Elastic Beanstalk environment.

4.    After the deployment is completed, log in to the instance running on the Elastic Beanstalk environment. After logging in, check that the settings to the NGINX server are applied. To do this, use the following command:

$ sudo nginx -T | egrep -i "client_max_body_size"
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
client_max_body_size 50M;

AWS OFFICIAL
AWS OFFICIALUpdated a year ago
14 Comments

We've been researching for days, but everything else on the net is outdated - this has worked now!

Step 3 had to be implemented specifically for our application. In our Spring Boot Java 8 application, the following snippet had to be added to the pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
    <executions>
        <execution>
            <id>prepare</id>
            <phase>package</phase>
            <configuration>
                <tasks>
                    <copy todir="${project.build.directory}/${project.build.finalName}/" overwrite="false">
                        <fileset dir="./" includes=".platform/**"/>
                        <fileset dir="${project.build.directory}" includes="*.jar"/>
                    </copy>
                    <zip destfile="${project.build.directory}/${project.build.finalName}.zip"
                         basedir="${project.build.directory}/${project.build.finalName}"/>
                </tasks>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>
profile picture
replied a year ago

Hi there! I've been the same journey for days and tried all the above procedures without success. As you can see attached I have the same structure in my project with the file and also included this in the POM.xml

 <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
        <executions>
          <execution>
            <id>prepare</id>
            <phase>package</phase>
            <configuration>
              <tasks>
                <copy todir="${project.build.directory}/${project.build.finalName}/"
                  overwrite="false">
                  <fileset dir="./" includes=".platform/**"/>
                  <fileset dir="${project.build.directory}" includes="*.jar"/>
                </copy>
                <zip destfile="${project.build.directory}/${project.build.finalName}.zip"
                  basedir="${project.build.directory}/${project.build.finalName}"/>
              </tasks>
            </configuration>
            <goals>
              <goal>run</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

But then, checking in the instance that's all I see:

[ec2-user@ip-XXXXXXX /]$ sudo nginx -T | egrep -i "client_max_body_size"
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Can you guys help me?

replied a year ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied a year ago

We researched it for days as well. Thought almost nothing would work. But if you just follow this link's answer "properly", it will work.

For us as well, Step 3 was the most important. Step 1,2 and 4 is pretty simple and understandable. However, step 3 can be different for different projects. We had our CI/CD through Github actions and changing some config to properly match step no. 3 through our "workflow" was extremely important.

Tried including ".platform" as root folder of the jar, did not work. Tried creating "Procfile" and ".platform" together. Still did not work.

However, only having ".platform" like mentioned by this link did the trick but then again, you have to be careful about step 3. You have to implement step 3 however you can in your project. That is the key.

kazi
replied a year ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied a year ago

I've tried all the available methods within .ebextensions to configure the implementation, but none of them worked with the latest Amazon Linux AMI. After extensive research and examining the deployment task runner logs, I discovered that it checks for a folder named .platform every time. I decided to create a similar structure within my project to see if it would work.

Here's what I did in the root folder of my project:

Folder structure (.platform/nginx/conf.d/proxy.conf):

 .platform/
  nginx/
    conf.d/
      proxy.conf

Content of File 1 - proxy.conf (Inside .platform/nginx/conf.d/ folder):

client_max_body_size 50M;

Content of File 2 - 00_myconf.config (Inside .platform/ folder):

container_commands:
  01_reload_nginx:
    command: "service nginx reload"

Please be cautious with the file extensions: the first file uses .conf, and the second file uses .config.

After making these changes, I redeployed my project to Amazon Elastic Beanstalk, and it worked. This configuration was applied to all the EC2 instances created as part of the auto-scaling group.

To apply these changes to your project, simply add the .platform folder setup to the root level of your project directory.

profile picture
replied 8 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 8 months ago

We have upgraded our EC2 instances to Corretto 17 running on 64bit Amazon Linux 2023/4.1.2. This solution does not appear to work for this environment, that is, the /etc/nginx/nginx.conf file is not updated with the client_max_body_size configuration parameter during the upload/build process as described above. When I update nginx.conf manually and restart nginx, I can upload files greater than 1 MB. Does anyone know of a solution where nginx.conf file is updated with client_max_body_size parameter during the upload/build process so that the file does not need to be edited manually?

Tom H
replied 3 months ago

Some notes for .net projects as documentation is thoroughly lacking.

@Ahmed Salem solution is what worked for me, .net core 6 and .net core 8 mvc and api applications. Place .platform folder at same directory as program.cs, so same dir level as wwwroot/controllers/bin directories within your project.

Structure looks like.

- wwwroot
- bin
- Controllers
- Program.cs
- .platform
        - nginx
        - 00_myconf.config
                - conf.d
                        - proxy.conf

or rather /.platform/nginx/00_myconf.config and /.platform/nginx/conf.d/proxy.conf

all within the top level directory.

Once files added, in the properties within visual studio of each file set Build Action to Content and Copy to Output Directory to Copy If Newer.

Then build / deploy using beanstalk and it should work. Instance i'm using at moment is .NET Core running on 64bit Amazon Linux 2/2.6.3

profile picture
replied 2 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 2 months ago

@dwimbley In .net web api 6 I m using github And codePipeLine To build and deploy to elastic beanstalk Kindly tell me how to do it there ? I created the above directories and files but it wont work

Ibnx
replied 2 months ago

Is updating the version in your code required for this to take affect?

3. Deploy your code and the new .platform/ directory together as a new application version in your Elastic Beanstalk environment.

con_rad
replied 2 months ago

@con_rad - updating version in code is not required. Beanstalk / CLI will actually increment a version# it needs in order to track which build to deploy through the CLI.

So no, no need to increase the .net version# within .net project itself.

profile picture
replied 2 months ago

@Ibnx if you can provide your folder structure I can take a look, but you may also need to increase file size handling within your project by placing Request Size Limit on top of your action.

Ex:

[HttpPost]
[RequestSizeLimit(200_000_000)]
public IActionResult FileUpload(List<IFormFile> file)

If those don't work you could also try

[HttpPost, DisableRequestSizeLimit]
public IActionResult FileUpload(List<IFormFile> file)

or

[HttpPost, RequestFormLimits(MultipartBodyLengthLimit = Int32.MaxValue, ValueLengthLimit = Int32.MaxValue)]
public IActionResult FileUpload(List<IFormFile> file)

As other potential examples.

profile picture
replied 2 months ago