I know there are a lot of SO questions on this exact topic. However, none seem to work with the latest version of Elastic Beanstalk / Docker combination.
I am running a Django/Python web app inside a Docker, which I then deploy to Elastic Beanstalk. I want http and https to be active, so I enabled both port 80 and 443 in the AWS EB configuration console. This works great. My site is accessible over both http and https. However, this isn't really what I want. I want port 80 (http) automatically forward to port 443 (https).
I've followed every piece of advice out there on SO and other forums to debug this, but I think the info out there is too old. (Ie., this no longer works).
I have found where EB sets up its servers (in a file called: /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf
), and it's contents are:
map $http_upgrade $connection_upgrade {
default "upgrade";
"" "";
}
server {
listen 80;
location / {
proxy_pass http://docker;
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;
}
}
When I modify this file from listen 80;
to listen 443 ssl;
and the try to load my site on https, I get ERR_CONNECTION_REFUSED
.
Can someone point me in the correct direction to modify this config file to redirect from http to https?
Select a load balancer, and then choose HTTP Listener. Under Rules, choose View/edit rules. Choose Edit Rule to modify the existing default rule to redirect all HTTP requests to HTTPS.
Elastic Beanstalk uses nginx as the reverse proxy to map your application to your Elastic Load Balancing load balancer on port 80. Elastic Beanstalk provides a default nginx configuration that you can either extend or override completely with your own configuration.
As of August 2018, for a Python (Flask) app placed in a Docker container with nginx placed in front and SSL certificate in AWS Certificate Manager.
After configuring the load balancer to listen on both ports 80 and 443 you can configure the redirection from http to https by creating one file. In general, it will add one if
statement into an nginx configuration for you:
if ($http_x_forwarded_proto = 'http') {
return 301 https://$host$request_uri;
}
TL;DR: This is done by the following file placed in .ebextensions
directory which you create in the parent directory of your Beanstalk app project. Give the file a chosen name, for e.g. force-https
, but remember to use the .config
extension. Don't forget to commit the new file if you're using git!
My app/.ebextensions/force-https.config
file (YAML - indentation matters!):
files:
"/etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf" :
mode: "000755"
owner: root
group: root
content: |
map $http_upgrade $connection_upgrade {
default "upgrade";
"" "";
}
server {
listen 80;
gzip on;
gzip_comp_level 4;
gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
set $year $1;
set $month $2;
set $day $3;
set $hour $4;
}
access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
access_log /var/log/nginx/access.log;
location / {
if ($http_x_forwarded_proto = 'http') {
return 301 https://$host$request_uri;
}
proxy_pass http://docker;
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;
}
}
Explanation: If you want the redirection to work for every new deployment and every new EC2 instance that will be started for your app, you need to modify the nginx configuration through Elastic Beanstalk .ebextensions
directory. In theory, this change could be done directly in the app's EC2 instance's nginx configuration file (using ssh
to connect to the machine), this however is not a good solution, because the changes will be lost when the instance is terminated or when you deploy a new version of the app.
The file where we intend to add the aforementioned if
statement is placed in /etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf
in the app's EC2 instance. Our file with replacement instructions needs to be created in the .ebextensions
directory that you create in the parent directory of your project. It needs to specify which files you want to overwrite (files:
in the code above). Elastic Beanstalk will apply this .config
file while deploying your app by overwriting the indicated nginx file in every new machine.
Have you tried configuring this in settings.py and let django handle the process.
SECURE_SSL_REDIRECT = True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With