Reputation: 7746
I have deployed a Spring Boot REST application as a WAR into an AWS Elastic Beanstalk Tomcat 8 + Java 8 instance. Subsequently, I realized that I need to configure the following settings (applies to the Tomcat server.xml):
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/css,..."
because application.properties
in Spring Boot applies only to embedded Tomcat containers. It is too late to change the platform type of the Elastic Beanstalk instance now. Is there any way to update the configuration from the Elastic Beanstalk CLI, using eb config
? I was looking at this AWS page, and it looks like it may be possible.
Updated 01/16/2017 Thanks to the answer from @dave-maple I started looking in the relevant parts of Elastic Beanstalk documentation.
First, I discovered that Apache is the default proxy server. I could have changed it to nginx, but I didn't have any particular justification to go that route.
Second, I found that adding an .ebextensions
folder to the top level of my Spring Boot project. I did not want to pollute my code base with a cloud provider specific configuration file, but it seemed to be the lowest hanging fruit. So I went for it.
I added the following hierarchy:
MySpringBootProject
|
+- src
|
+- main
|
+- resources
|
+- ebextensions
|
+- httpd
| |
| +- conf.d
| |
| +- enable_mod_deflate.conf
|
+- myapp.config
|
+- tomcat-settings.config
Contents of tomcat-settings.config
option_settings:
aws:elasticbeanstalk:environment:proxy:
GzipCompression: 'true'
Contents of myapp.config
container_commands:
05-restart-apache:
command: "sudo /etc/init.d/httpd restart"
Contents of enable_mod_deflate.conf
# mod_deflate configuration
<IfModule mod_deflate.c>
# Restrict compression to these MIME types
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xml+rss
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE image/png
AddOutputFilterByType DEFLATE image/gif
AddOutputFilterByType DEFLATE image/jpeg
# Level of compression (Highest 9 - Lowest 1)
DeflateCompressionLevel 9
# Netscape 4.x has some problems.
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
<IfModule mod_headers.c>
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</IfModule>
</IfModule>
Add the following lines to pom.xml (to set up the .ebextensions
folder in the top level of the generated WAR file):
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>src/main/resources/ebextensions</directory>
<targetPath>.ebextensions</targetPath>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
I could have sworn this worked, because I saw the Content-Encoding: gzip
response header... only a couple of times. Any idea what could be happening?
Upvotes: 0
Views: 1447
Reputation: 8422
The best way to implement compression would be at the nginx proxy which runs in front of tomcat. nginx is more efficient at this operation. To do this you can create an .ebextensions
directory in the root of your deployment archive and add an nginx-proxy.config
file such as the following:
.ebextensions/nginx-proxy.config
option_settings:
aws:elasticbeanstalk:environment:proxy:
GzipCompression: 'true'
ProxyServer: nginx
Then you can build and deploy the new version of your app on Elastic Beanstalk.
If you need to avoid downtime when rolling out the new version you can use a rolling deployment (takes instances out of LB before deployment new versions) or even blue/green deployment (a new environment + cname swap).
=== EDIT ===
You may need to customize the Content-Type
values that nginx will gzip.
To gzip everything, create a config file in .ebextensions:
.ebextensions/gzip.config
files:
/etc/nginx/conf.d/gzip.conf:
content: |
gzip_types *;
or to be more selective, define the types you want compressed:
.ebextensions/gzip.config
files:
/etc/nginx/conf.d/gzip.conf:
content: |
gzip_types text/plain text/css application/json application/x-javascript text/xml;
Upvotes: 1