Documentation on how to override or extend the default nginx config on Elastic Beanstalk running om Amazon Linux 2. Correct as of 2021-08-01. Also see the general documentation on how to extend linux servers.
All references to placing files refer to putting a file at this location in your application bundle. You should never modify a file directly at your Elastic Beanstalk server by ssh:ing to the server, since such a change will be wiped whenever your servers autoscale or if you rebuild your application completely.
The easiest extension is to add a new location block to the main server block. This can be done by placing a .conf
file with a server block in the folder .platform/nginx/conf.d/elasticbeanstalk
. Any such file is automatically included in the main server block.
The default location block is most easily overridden by placing a file in the bundle at the location .platform/nginx/conf.d/elasticbeanstalk/00_application.conf
. This will simply replace the default block provided by elastic beanstalk.
The default block looks like this (for node.js code - 2021-07-25 - other languages might run on a different port):
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
(Note that it might be a better idea to let the application load balancer handle this by redirecting traffic on port 80 to port 443 directly: https://aws.amazon.com/premiumsupport/knowledge-center/elb-redirect-http-to-https-using-alb/).
HTTPS can be forced by adding the following to the location block (note that it allows the health checker to use HTTP):
set $redirect 0;
if ($http_x_forwarded_proto != "https") {
set $redirect 1;
}
if ($http_user_agent ~* "ELB-HealthChecker") {
set $redirect 0;
}
if ($redirect = 1) {
return 301 https://$host$request_uri;
}
Basic auth can be activated by adding the following to the location block:
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
Note that you will then have to write the content to the .htpasswd
file somehow. This can either be done by placing a files block in a config file in the .ebextensions
folder (see documentation), or by running some kind of script to write the file. Such a script should be an executable file placed in either .platform/hooks/predeploy
or .platform/confighooks/predeploy
depending on how the content for the .htpasswd
file is generated.
If you want to pass the auth basic credentials to the backend, add this as well:
proxy_set_header Authorization $http_authorization;
It will then be set as Authorization header in the backend. The content of this header will be Basic
followed by the string username:password
encoded as Base64.
To make the health check work with basic auth, you can set up a separate location block that does not require basic auth. Don't give this path access to any sensitive information, only to a basic healt check. Here's an example that allows the health check to access /elb-status
, which is then passed on to a status route in the application:
location /elb-status {
proxy_pass http://127.0.0.1:8080/status;
}
The default nginx config will load any config file ending with .conf
and placed in .platform/nginx/conf.d
. You can use this to create new server blocks. This is the way to go if you need to do more than extend the default server block. If you create new server blocks you will have to check how nginx will prioritize the traffic. See https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms.
To get complete control of the nginx configuration, it is possible to override the whole config. This is done by placing a full nginx configuration as .platform/nginx/nginx.conf
. Only do this if you have to, since you will have to manually check if there is any changes to the default config for new releases to make sure that your configuration is still valid.
If you decide to override the full config, it is a good idea to include the content of the file found in /etc/nginx/conf.d/elasticbeanstalk/health.conf
to get the health checking config as well (this also goes for new server blocks).
The following is the current nginx config used for node.js applications (as of 2021-07-25). It is mainly here for reference. You should ssh to your instance and check the currrent configuration to make sure that you're manipulating the latest version.
# Elastic Beanstalk Nginx Configuration File
user nginx;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 32633;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
include conf.d/*.conf;
map $http_upgrade $connection_upgrade {
default "upgrade";
}
server {
listen 80 default_server;
access_log /var/log/nginx/access.log main;
client_header_timeout 60;
client_body_timeout 60;
keepalive_timeout 60;
gzip off;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
include conf.d/elasticbeanstalk/*.conf;
}
}
Much documentation provided by Amazon is invalid since the behavior has changed for Amazon Linux 2. This config (and the rest of the repo from how it looks) for example only works for Amazon Linux 1: https://github.com/awsdocs/elastic-beanstalk-samples/blob/master/configuration-files/aws-provided/security-configuration/https-redirect/nodejs/https-redirect-nodejs.config
Hi @maxkremer, did you finally found a way to enable gzip by any chance? We have the same problem.